属性上的SQL XML DIFF

时间:2014-06-27 09:11:54

标签: sql xml

我在表中有一个XML字段,并希望设置一个触发器来存储另一个表中的更改。 我想知道,例如,属性“url”已从“http://example.com/”更改为“http://newurl.com”以及何时。

这就是我现在所拥有的:

DECLARE @XML1 XML
DECLARE @XML2 XML

SET @XML1 = 
'<NewDataSet> 
<Employee>
<EmpID>1005</EmpID>
<Name> keith </Name>
<DOB>12/02/1981</DOB>
<DeptID>ACC001</DeptID>
</Employee>
</NewDataSet>'

SET @XML2 = 
'<NewDataSet> 
<Employee>
<EmpID>1005</EmpID>
<Name> keith </Name>
<DOB>12/02/1981</DOB>
<DeptID>ACC002</DeptID>
</Employee>
</NewDataSet>'


;with XML1 as
(
  select T.N.value('local-name(.)', 'nvarchar(100)') as NodeName,
         T.N.value('.', 'nvarchar(100)') as Value
  from @XML1.nodes('/NewDataSet/Employee/*') as T(N)
),
XML2 as
(
  select T.N.value('local-name(.)', 'nvarchar(100)') as NodeName,
         T.N.value('.', 'nvarchar(100)') as Value
  from @XML2.nodes('/NewDataSet/Employee/*') as T(N)
)
select coalesce(XML1.NodeName, XML2.NodeName) as NodeName, 
       XML1.Value as OldVal, 
       XML2.Value as NewVal,
       GETUTCDATE() as changed
from XML1
  full outer join XML2
    on XML1.NodeName = XML2.NodeName
where coalesce(XML1.Value, '') <> coalesce(XML2.Value, '')  

但它仅适用于节点值,我希望它也适用于属性。

我希望它工作的XML文件示例:

<crawlsetup>
  <go param="" url="http://www.example.com/index.php">
    <match param="" match="href=&quot;(/job[^&quot;]+)&quot;" url="http://www.example.com$1" save1="" save2="" save3="">
        <match param="" match="href=&quot;(/job[^&quot;]+)&quot;" url="http://www.example.com$1" save1="" save2="" save3="" />
        <next match="" url="$1" />
    </match>
  </go>
</crawlsetup>

可能有几个属性,我想检测所有属性的变化。

有人可以帮我这个吗? 谢谢=)

2 个答案:

答案 0 :(得分:1)

如果您只想选择元素的一个属性(例如url),请使用此XPath表达式:

from @XML2.nodes('/crawlsetup/go/@url') as T(N)

要选择元素的所有属性,请使用以下属性:

from @XML2.nodes('/crawlsetup/go/@*') as T(N)

答案 1 :(得分:0)

在节点功能中使用序列。添加/NewDataSet/Employee/@*

;with XML1 as
(
  select T.N.value('local-name(.)', 'nvarchar(100)') as NodeName,
         T.N.value('.', 'nvarchar(100)') as Value
  from @XML1.nodes('/NewDataSet/Employee/*, /NewDataSet/Employee/@*') as T(N)
),
XML2 as
(
  select T.N.value('local-name(.)', 'nvarchar(100)') as NodeName,
         T.N.value('.', 'nvarchar(100)') as Value
  from @XML2.nodes('/NewDataSet/Employee/*, /NewDataSet/Employee/@*') as T(N)
)
select coalesce(XML1.NodeName, XML2.NodeName) as NodeName, 
       XML1.Value as OldVal, 
       XML2.Value as NewVal,
       GETUTCDATE() as changed
from XML1
  full outer join XML2
    on XML1.NodeName = XML2.NodeName
where coalesce(XML1.Value, '') <> coalesce(XML2.Value, '')