我有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值的值。
有什么想法吗? 提前谢谢!
答案 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