T-SQL:比较2个XML并返回具有不同值的节点

时间:2017-10-12 15:01:40

标签: sql-server sql-server-2008 tsql sql-server-2005

我有2个xml变量(@ xml1& @ xml2),我需要比较每个节点中的值并返回一个只包含不同节点的xml。

所以说,我有这两个XML变量:

declare @xml1 xml = N'<row>
  <id>1</id>
  <name>record title</name>
  <description>sample description</description>
</row>'
declare @xml2 xml = N'<row>
  <id>1</id>
  <name>record title</name>
  <description>updated sample description</description>
</row>'

我希望它能够回归:

SELECT @xml1 = N'<row>
  <description>sample description</description>
</row>', @xml2 = N'<row>
  <description>updated sample description</description>
</row>'

我有以下查询返回我需要的东西,但是它的UNpivoted&amp;没有xml节点等:

SELECT
        NV.NodeName,
        OV.NodeValue OldValue,
        NV.NodeValue NewValue
FROM 
(SELECT T.N.value('local-name(.)', 'nvarchar(100)') NodeName,
                T.N.value('.', 'nvarchar(100)') NodeValue
            FROM @xml1.nodes('/row/*') T(N)) NV
CROSS APPLY (SELECT T.N.value('local-name(.)', 'nvarchar(100)') NodeName,
                T.N.value('.', 'nvarchar(100)') NodeValue
            FROM @xml2.nodes('/row/*') T(N)) OV
WHERE OV.NodeName = NV.NodeName AND OV.NodeValue <> NV.NodeValue

性能至关重要:此代码处于触发状态,因此需要快速运行并且我害怕使用PIVOT,因为它往往很慢。我希望有更好的方法来比较和返回已经作为xml值的值。

有什么想法吗? 提前谢谢!

1 个答案:

答案 0 :(得分:0)

没关系 - 想出来=) 如果这有助于任何人在路上:

DECLARE @ XMLString1 VARCHAR(MAX)='',         @XMLString2 VARCHAR(MAX)='';

SELECT @XMLString1 += '<' + OV.NodeName + '>' + LEFT(OV.NodeValue, 8000) + '</' + OV.NodeName + '>',
       @XMLString2 += '<' + NV.NodeName + '>' + LEFT(NV.NodeValue, 8000) + '</' + NV.NodeName + '>'
FROM 
    (SELECT T.N.value('local-name(.)', 'varchar(255)') NodeName,
            T.N.value('.', 'varchar(8000)') NodeValue
    FROM @xml1.nodes('/row/*') T(N)) NV
CROSS APPLY 
    (SELECT T.N.value('local-name(.)', 'varchar(255)') NodeName,
            T.N.value('.', 'varchar(8000)') NodeValue
    FROM @xml2.nodes('/row/*') T(N)) OV
WHERE OV.NodeName = NV.NodeName AND OV.NodeValue <> NV.NodeValue
SET @XMLString1 = '<row>' + ISNULL(@XMLString1, '') + '</row>';
SET @XMLString2 = '<row>' + ISNULL(@XMLString2, '') + '</row>';

SELECT CONVERT(XML, @XMLString1) xml1, CONVERT(XML, @XMLString2) xml2