如何比较mssql中的两个xml文件

如何比较mssql中的两个xml文件,sql,sql-server,xml,sql-server-2012,Sql,Sql Server,Xml,Sql Server 2012,我有两个类型的文件: @xmlAuthors1 XML =N' <Author name="John" surname="Clinton" /> <Author name="Bill" surname="Skobov" /> <Author name="John" surname="Lokwood" />; @xmlAuthors2 XML =N' <Author name="Bill" surn

我有两个类型的文件:

@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中的每一行进行比较,例如,您可以通过如下方式进行比较:

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

如果存在相等值,则不会有输出。例如,您可以将它们进行比较,如:

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

如果存在相等,则不会有输出

这取决于相等对您意味着什么。我将比较以下数据:

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

这取决于平等对你意味着什么。我将比较以下数据:

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
这就是我的方法:

使用.query.data.value可以很好地将所有内部文本检索为空格分隔的字符串。这使得在字符串级别进行比较变得很容易

我将您的输入更改为包含更多测试用例:

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
这就是我的方法:

使用.query.data.value可以很好地将所有内部文本检索为空格分隔的字符串。这使得在字符串级别进行比较变得很容易

我将您的输入更改为包含更多测试用例:

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

你有没有用不相等的数据来测试这个?只是看得更近一点。。。你的想法和我的想法非常接近,你将整个元素转换为字符串。。。但是在哪里x1!=x2不处理空值,空值表示完整外部联接中缺少的值…是的,我已经测试过,如果x1有值,x2为空,或者x1为空,x2有值,或者我不理解,但您的示例没有运行,它只在需要找到相等的行时才被激活。操作不等于不显示任何内容,当行不同时,或它们的编号不同时。非常奇怪,我稍后会重新检查。在我提供的一个示例中,它输出两行,如果从“Johns”中删除“s”-没有行,这是昨天我检查时的结果。您是否使用不相等的数据进行了测试?只是看得更近一些。。。你的想法和我的想法非常接近,你将整个元素转换为字符串。。。但是在哪里x1!=x2不处理空值,空值表示完整外部联接中缺少的值…是的,我已经测试过,如果x1有值,x2为空,或者x1为空,x2有值,或者我不理解,但您的示例没有运行,它只在需要找到相等的行时才被激活。操作不等于不显示任何内容,当行不同时,或它们的编号不同时。非常奇怪,我稍后会重新检查。在我提供的一个示例中,它输出两行,如果从“Johns”中删除“s”-没有行,这是昨天我检查的。