2011-09-15 47 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