Sql server Sql Server XML类型列重复条目检测

Sql server Sql Server XML类型列重复条目检测,sql-server,xml,Sql Server,Xml,在SQLServer中,我使用XML类型的列来存储消息。我不想存储重复的邮件 我只会有几个消息,每个用户。我目前正在查询表中的这些消息,将XML转换为C代码中的字符串。然后将字符串与我要插入的内容进行比较 不幸的是,SQLServerPretty在XML类型的字段中打印数据。存储到数据库中的内容不一定与稍后返回的内容完全相同。它在功能上是等效的,但可能会删除空白等 有没有一种有效的方法来比较我正在考虑插入的XML字符串与数据库中已经存在的XML字符串?另一方面,如果我检测到重复,我需要删除旧邮件

在SQLServer中,我使用XML类型的列来存储消息。我不想存储重复的邮件

我只会有几个消息,每个用户。我目前正在查询表中的这些消息,将XML转换为C代码中的字符串。然后将字符串与我要插入的内容进行比较

不幸的是,SQLServerPretty在XML类型的字段中打印数据。存储到数据库中的内容不一定与稍后返回的内容完全相同。它在功能上是等效的,但可能会删除空白等


有没有一种有效的方法来比较我正在考虑插入的XML字符串与数据库中已经存在的XML字符串?另一方面,如果我检测到重复,我需要删除旧邮件,然后插入替换邮件。

0-向表中添加哈希列

1-收到新消息时,将整个XML转换为大写,删除所有空格并返回/linefeed,然后计算规范化字符串的哈希值

2-检查是否已经有一行包含结果哈希代码

如果是,这是重复的,处理它 照着 如果不是,则将原始XML与哈希一起存储在新行中
一种解决方案是停止使用XML类型字段。将XML字符串存储到varchar类型的字段中


我不太喜欢这个解决方案,但我也不太喜欢p.marino的解决方案。存储表中行中已有内容的散列似乎不正确。

如果在表中的每一行上使用OPENXML并查询键节点和/或键属性的实际XML信息,会怎么样?但是,您需要逐行执行,我认为OPENXML不能处理一整套表行。

我不能100%确定您的具体实现,但这里有一些我曾经玩过的东西。作为存储过程的想法可以实现插入。插入到messages表中会对现有的messages 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  
)

+一个好问题!这是XML的一个棘手的方面——恐怕没有简单的解决方案……失去了兴趣?找到更好的解决方案了吗?@p.marino:不,我没有完全失去兴趣。我愿意接受您的解决方案,但是存储数据库中已有内容的哈希似乎不合适。我几乎宁愿放弃使用XML类型字段,而回到varchar。我会将其作为“解决方案”添加,但我也不认为这是正确的。迂腐的注释:不要求值相等,因为哈希代码是,但是如果使用SHA1或MD5或其他什么,冲突的风险是可以忽略的。非迂腐的注释:您甚至可以创建一个函数来执行此计算CLR,为值创建一个计算列,并在计算列上创建一个唯一的索引。@erikallen:不需要CLR函数,只需使用内置的HASHBYTES我想我不需要执行字符串规范化,这是您的第一步。我可以计算原始消息字符串上的哈希值,那么重复项的比较仍然是准确的。我的重复测试是检测将要存储的原始邮件上的重复项。你好不应该等同于你好,那就更好了。什么类型的规范化,即你认为在格式、空间、案例等方面有意义的东西,当然是你需要根据具体情况来评估的。它对于检测预进入或处理同一XML数据的各种表示的问题没有多大用处,但我最近遇到了一个类似的问题,即检测现有数据中的重复数据,在阅读了这个答案后,我尝试了散列方法。我最终决定进行简单的字符串比较,性能不成问题,并了解了如果要提出一个健壮的哈希解决方案,我必须走的方向。我在这里写下了我的经历