2010-03-09 67 views
3

在Sql Server中我使用XML類型列來存儲消息。我不想存儲重複的消息。Sql Server XML類型列重複條目檢測

我只會爲每個用戶發送幾條消息。我目前正在查詢這些消息的表格,將XML轉換爲C#代碼中的字符串。然後我將這些字符串與我即將插入的內容進行比較。

不幸的是,Sql Server漂亮地打印XML類型字段中的數據。存儲到數據庫中的內容不一定與您稍後返回的字符串完全相同。它在功能上是等效的,但可能已刪除空格等。

是否有一種有效的方法來比較我正在考慮插入的XML字符串與已經在數據庫中的字符串?另外,如果我檢測到重複,我需要刪除舊信息,然後插入替換。

+0

+1好問題!這是XML中棘手的方面之一 - 我不是一個簡單的解決方案,恐怕...... – 2010-03-09 18:22:09

+0

失去了興趣?找到更好的解決方案? – 2010-03-17 10:11:58

+0

@ p.marino:不,我沒有完全失去興趣。我想接受你的解決方案,但是存儲數據庫中已有內容的散列似乎並不正確。我幾乎寧願放棄使用XML類型字段,然後回到varchar。我會將此添加爲「解決方案」,但我不會接受這一點。 – 2010-03-17 20:21:19

回答

2

0 - 添加一個哈希列到表

1 - 當你收到一個新的消息,將整個XML爲大寫,刪除所有空格,並返回/換行,然後計算標準化的字符串的哈希值。

2 - 檢查您是否已經有一行包含生成的哈希碼。

  • 如果是的話,這是重複的,把它 相應
  • 如果不是這樣,原來的XML與散列一起存儲在一個新行
+0

迂腐筆記:由於哈希代碼的值不是必須的,但如果使用SHA1或MD5或其他東西,則碰撞風險可以忽略不計。非迂腐的筆記:您甚至可以創建一個函數來執行此計算(也許是CLR),爲該值創建一個計算列,並在計算列上創建一個唯一索引。 – erikkallen 2010-03-09 18:27:12

+1

@erikallen:不需要CLR函數,只需使用內置的HASHBYTES http://msdn.microsoft.com/en-us/library/ms174415.aspx – 2010-03-09 19:02:45

+0

我不認爲我需要做字符串規範化,你的步驟1。我可以計算原始消息字符串的散列值,然後重複的比較仍然是準確的。我的重複測試是檢測將要存儲的原始消息的重複項。 (「你好」不應該等於「HELLO」)。 – 2010-03-09 20:52:57

0

一種解決方案是停止使用類型化的XML領域。將XML字符串存儲到varchar類型的字段中。

我不太喜歡這個解決方案,但我也不太喜歡p.marino的解決方案。存儲表中已存在行的散列似乎不正確。

0

如果您在表中的每一行上使用OPENXML並查詢關鍵節點和/或關鍵屬性的實際XML信息,該怎麼辦?但是,你需要逐行進行,我不認爲OPENXML可以處理一整套表格行。

1

我不是100%確定您的具體實施,但這是我玩過的東西。作爲一個存儲過程的想法會做插入。插入消息表對現有消息進行基本檢查(SQL 2008語法):

declare @messages table (msg xml) 
insert into @messages values 
('<message>You like oranges</message>') 
,('<message>You like apples</message>') 

declare @newMessage xml = '<message>You like apples</message>' 

insert into @messages (msg) 
select @newMessage 
where @newMessage.value('(message)[1]', 'nvarchar(50)') not in (
    select msg.value('(message)[1]', 'nvarchar(50)') 
    from @messages 
)