2011-09-15 42 views
2

我有两个真正包含XML数据的NVARCHAR字段相同的表。 在某些情况下,这个真正的XML字段与其他表中的一行真的相同,但的属性顺序不同,因此字符串比较不会返回正确的结果!比较SQL中的Xml数据

,并确定相同的XML领域,我需要有这样一个比较:

cast('<root><book b="" c="" a=""/></root>' as XML) 
= cast('<root><book a="" b="" c=""/></root>' as XML) 

,但我得到这个错误消息:

XML数据类型不能比较或排序,除了使用012 NULL空操作符时。

那么确定相同的XML而不将它们重新转换为NVARCHAR的最佳解决方案是什么?

+2

比较XML不仅仅是语法上的,而是基于XML文本表示的实际**含义**实际上是相当棘手的业务。我非常怀疑你可以在SQL Server中轻松完成这个任务 - 很可能你必须使用一个应用程序来解析和解释XML,以确定它是相同的还是不同的。一个简单的文本比较将不容易或足够...... –

+0

请不要尝试在sql中滚动您自己的XML解析器。使用可以从您选择的语言中使用的已建立的一个。 –

回答

2

为什么投它呢?只需将它们插入临时表中的XML列并运行Xquery以将它们与其他表进行比较。编辑:包括比较的例子。有很多种方法可以对XML运行查询以获得相同的行 - 查询写入的方式取决于首选项,需求等。我使用/ count作为简单组,但是可以使用自连接,WHERE EXISTS针对正在搜索重复项的列,您将其命名。

CREATE TABLE #Test (SomeXML NVARCHAR(MAX)) 
CREATE TABLE #XML (SomeXML XML) 

INSERT #Test (SomeXML) 
VALUES('<root><book b="b" c="c" a="a"/></root>') 
    ,('<root><book a="a" b="b" c="c"/></root>') 

INSERT #XML (SomeXML) 

SELECT SomeXML FROM #Test; 

WITH XMLCompare (a,b,c) 
AS 
(
SELECT 
    x.c.value('@a[1]','char(1)') AS a 
    ,x.c.value('@b[1]','char(1)') AS b 
    ,x.c.value('@c[1]','char(1)') AS c 
FROM #XML 
CROSS APPLY SomeXMl.nodes('/root/book') X(C) 
) 

SELECT 
    a 
    ,b 
    ,c 
FROM XMLCompare as a 
GROUP BY 
    a 
    ,b 
    ,c 
HAVING COUNT(*) >1 
+0

那么如何比较它们呢? – ARZ

+0

@ARZ,XQuery。通过比较发布修订。 – Wil

+0

感谢4您的回复。但如何直接比较整个XML的主体? (没有单独比较所有属性) – ARZ