2016-07-26 32 views
1

我有2個文件類型:如何比較兩個XML文件在MSSQL

@xmlAuthors1 XML =N' 
     <Author name="John" surname="Clinton" /> 
     <Author name="Bill" surname="Skobov" /> 
     <Author name="John" surname="Lokwood" />; 

@xmlAuthors2 XML =N' 
     <Author name="Bill" surname="Skobov" /> 
     <Author name="John" surname="Clinton" /> 
     <Author name="John" surname="Lokwood" />; 

如何發現他們是平等的嗎?比較文件1的每一行從文件2

+1

見http://stackoverflow.com/questions/9013680/t-sql-how-can-i-compare-two-variables-of-type-xml-when-length-varcharmax – Serg

回答

3

例如每一行,您可以對它們進行比較,如:

DECLARE @xmlAuthors1 XML = N' 
       <Author name="John" surname="Clinton" /> 
       <Author name="Bill" surname="Skobov" /> 
       <Author name="John" surname="Lokwood" />', 
     @xmlAuthors2 XML =N' 
       <Author name="Bill" surname="Skobov" /> 
       <Author name="Johns" surname="Clinton" /> 
       <Author name="John" surname="Lokwood" />' 


SELECT * 
FROM (
    SELECT CAST(x1.t.query('.') as nvarchar(max)) as x1, 
      CAST(x2.t.query('.') as nvarchar(max)) as x2 
    FROM @xmlAuthors1.nodes('/*') as x1(t) 
    FULL OUTER JOIN @xmlAuthors2.nodes('/*') as x2(t) 
     ON CAST(x1.t.query('.') as nvarchar(max)) = CAST(x2.t.query('.') as nvarchar(max)) 
) as x 
WHERE x1 is null or x2 is null 

如果有等於就沒有輸出

+0

你測試這個數據不相等? – Shnugo

+1

只是看起來更近一點......你的想法與我的非常接近,你將完整的元素作爲字符串進行投射......但是WHERE x1!= x2'不處理NULL值,它表示缺失的值從'FULL OUTER JOIN' ... – Shnugo

+0

是的,我測試過了,如果x1有值並且x2爲空或者x1爲空並且x2爲值,那麼可以正常工作。 – gofr1

1

這取決於什麼等於你的意思。

DECLARE @xmlAuthors1 XML =N' 
     <Author name="John" surname="Clinton" /> 
     <Author name="Bill" surname="Skobov" /> 
     <Author name="John" surname="Lokwood" /> 
     <Author name="John" surname="Blurred" />'; 

DECLARE @xmlAuthors2 XML =N' 
     <Author name="Bill" surname="Skobov" /> 
     <Author name="John" surname="Clinton" /> 
     <Author name="John" surname="Lokwood" />'; 

WITH Xml1 AS 
(
    SELECT 
     T.A.value('@name', 'varchar(20)') Name, 
     T.A.value('@surname', 'varchar(20)') Surname 
    FROM @xmlAuthors1.nodes('/Author') T(A) 
), Xml2 AS 
(
    SELECT 
     T.A.value('@name', 'varchar(20)') Name, 
     T.A.value('@surname', 'varchar(20)') Surname 
    FROM @xmlAuthors2.nodes('/Author') T(A) 
) 
SELECT 'Unique in 1' [Description], * FROM (SELECT * FROM Xml1 EXCEPT SELECT * FROM Xml2) Q1 
UNION ALL 
SELECT 'Unique in 2' [Description], * FROM (SELECT * FROM Xml2 EXCEPT SELECT * FROM Xml1) Q2 

這個特殊的例子產量:我將如下的數據進行比較

Description Name Surname 
----------- ---- ------- 
Unique in 1 John Blurred 
1

這是我的方法:

有一個很好的技巧與.query(.data()).value()檢索所有內部文本的空間分隔串。這可以很容易地在串級比較...

我改變了你輸入到inlcude一些測試案例:如果你想找到那些等於在這兩個你可以使用此

DECLARE @xmlAuthors1 XML = N' 
       <Author name="John" surname="Clinton" /> 
       <Author name="Bill" surname="Different" /> 
       <Author name="John" surname="Lokwood" /> 
       <Author name="Test" surname="it" />', 
     @xmlAuthors2 XML =N' 
       <Author name="Bill" surname="Skobov" /> 
       <Author name="John" surname="Clinton" /> 
       <Author name="John" surname="Lokwood" /> 
       <Author name="One" surname="More" />'; 

SELECT ISNULL(Author1,Author2) AS Author 
     ,CASE WHEN Author1 IS NULL THEN 'Exists in 2' ELSE 'Exists in 1' END AS [Source] 
FROM 
(
    SELECT B.query('data(@*)').value('.','varchar(max)') AS Author1 
    FROM @xmlAuthors1.nodes('/Author') AS A(B) 
) AS tbl1 
FULL OUTER JOIN 
( 
    SELECT B.query('data(@*)').value('.','varchar(max)') As Author2 
    FROM @xmlAuthors2.nodes('/Author') AS A(B) 
)AS tbl2 ON Author1=Author2 
WHERE Author1 IS NULL OR Author2 IS NULL 

SELECT B.query('data(@*)').value('.','varchar(max)') AS EqualAuthor 
FROM @xmlAuthors1.nodes('/Author') AS A(B) 
INTERSECT 
SELECT B.query('data(@*)').value('.','varchar(max)') 
FROM @xmlAuthors2.nodes('/Author') AS A(B)