首页 > 解决方案 > 如何根据同一节点中不同属性值的匹配来查找和更新 XML 文档中的节点属性值?

问题描述

给定我的 T-SQL 存储过程:

Declare @SearchID varchar(35)
Set @SearchID = '5280301.2019050148902.00023'

Declare @DocListXML XML  

包含以下 XML 数据

<JobList ListItems="7">
  <Job JobFriendlyName="EMAIL INVOICES">
    <DocumentList>
      <Document Doc="1" ID="5280301.2019050148902.00020" Date="05-03-2019" Status="NEW" />
      <Document Doc="2" ID="5280301.2019050148902.00022" Date="05-03-2019" Status="NEW" />
      <Document Doc="3" ID="5280301.2019050148902.00023" Date="05-03-2019" Status="NEW" />
      <Document Doc="4" ID="5280301.2019050104301.00055" Date="05-02-2019" Status="NEW" />
      <Document Doc="5" ID="5280301.2019050104301.00056" Date="05-02-2019" Status="NEW" />
    </DocumentList>
  </Job>
  <Job JobFriendlyName="INVOICES">
    <DocumentList>
      <Document Doc="6" ID="5280300.2019050148901.00001" Date="05-03-2019" Status="NEW" />
      <Document Doc="7" ID="5280300.2019050148901.00002" Date="05-03-2019" Status="NEW" />
    </DocumentList>
  </Job>
</JobList>

我需要 T-SQL XML 代码来更新此文档并将现有Status值替换为“OLD”,以用于具有ID与 T-SQL 局部变量的值匹配的属性值的节点@SearchID

更新后,生成的文档@DocListXML应包含:

<JobList ListItems="7">
  <Job JobFriendlyName="EMAIL INVOICES">
    <DocumentList>
      <Document Doc="1" ID="5280301.2019050148902.00020" Date="05-03-2019" Status="NEW" />
      <Document Doc="2" ID="5280301.2019050148902.00022" Date="05-03-2019" Status="NEW" />
      <Document Doc="3" ID="5280301.2019050148902.00023" Date="05-03-2019" Status="OLD" />
      <Document Doc="4" ID="5280301.2019050104301.00055" Date="05-02-2019" Status="NEW" />
      <Document Doc="5" ID="5280301.2019050104301.00056" Date="05-02-2019" Status="NEW" />
    </DocumentList>
  </Job>
  <Job JobFriendlyName="INVOICES">
    <DocumentList>
      <Document Doc="6" ID="5280300.2019050148901.00001" Date="05-03-2019" Status="NEW" />
      <Document Doc="7" ID="5280300.2019050148901.00002" Date="05-03-2019" Status="NEW" />
    </DocumentList>
  </Job>
</JobList>

我找到了修改/替换代码来修改“X”“Y”的属性值,但在属性 [b] 值与局部变量匹配的节点中找不到修改/更新更新属性 [a] 值的代码。

任何帮助或建议将不胜感激。

标签: sql-serverxmltsql

解决方案


好的,在您最后一个问题之后,您决定获得CURSOR路线,对吗?;-)

像这样试试。

--Your mockup up
Declare @SearchID varchar(35) = '5280301.2019050148902.00023';

Declare @DocListXML XML=
N'<JobList ListItems="7">
  <Job JobFriendlyName="EMAIL INVOICES">
    <DocumentList>
      <Document Doc="1" ID="5280301.2019050148902.00020" Date="05-03-2019" Status="NEW" />
      <Document Doc="2" ID="5280301.2019050148902.00022" Date="05-03-2019" Status="NEW" />
      <Document Doc="3" ID="5280301.2019050148902.00023" Date="05-03-2019" Status="NEW" />
      <Document Doc="4" ID="5280301.2019050104301.00055" Date="05-02-2019" Status="NEW" />
      <Document Doc="5" ID="5280301.2019050104301.00056" Date="05-02-2019" Status="NEW" />
    </DocumentList>
  </Job>
  <Job JobFriendlyName="INVOICES">
    <DocumentList>
      <Document Doc="6" ID="5280300.2019050148901.00001" Date="05-03-2019" Status="NEW" />
      <Document Doc="7" ID="5280300.2019050148901.00002" Date="05-03-2019" Status="NEW" />
    </DocumentList>
  </Job>
</JobList>';

--这是修改命令

SET @DocListXML.modify(N'replace value of (/JobList
                                           /Job
                                           /DocumentList
                                           /Document[@ID=sql:variable("@SearchID")]
                                           /@Status)[1] with "OLD"');

--检查结果

SELECT @DocListXML;

提示 1:这仅适用于每个 XML 只有一个具有给定 ID 的文档的情况!

提示 2:您可以将命令缩短为:

SET @DocListXML.modify(N'replace value of (//Document[@ID=sql:variable("@SearchID")]/@Status)[1] with "OLD"');

深度搜索//(由XPath 开头的双斜杠触发)告诉引擎在XML的任何位置<Document>找到一个完整的谓词。


推荐阅读