XQuery 不更新 XML 数据

S S*_*S S 7 xml sql-server update xquery

我正在尝试运行脚本来更新 XML 列:

UPDATE DataImpTable
SET serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1] with "9876"')
WHERE identifier=5
Run Code Online (Sandbox Code Playgroud)
UPDATE DataImpTable
SET serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1] with "9876"')
WHERE identifier=5
Run Code Online (Sandbox Code Playgroud)

将 的值更改ControlData为 9876,但该值在 XML 中似乎没有更改/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData

它与类型化和非类型化 XML 有什么关系?

Han*_*non 11

您需要在modify函数中声明命名空间。

像这样的东西:

DECLARE @xml xml = N'<SMObjInfo xmlns="DataService/1.0.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <CentralData>
    <SMData>
      <CentralSDItem>
        <ControlData>1234</ControlData>
      </CentralSDItem>
    </SMData>
  </CentralData>
</SMObjInfo>';
SET @xml.modify('
    declare default element namespace "DataService/1.0.0.0";
    replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem/ControlData/text())[1]
    with "6789"
    ');
PRINT CONVERT(nvarchar(max), @xml);
Run Code Online (Sandbox Code Playgroud)

在您的原始 xml 片段中,您声明了以下从未使用过的命名空间:

xmlns:i="http://www.w3.org/2001/XMLSchema-instance"

如果您的实际 xml 文档确实使用了此命名空间,并且您想要修改这些元素,则需要将以下声明添加到@xml.modify函数中:

declare namespace i="http://www.w3.org/2001/XMLSchema-instance";

结果(为了可读性而格式化):

<SMObjInfo xmlns="DataService/1.0.0.0" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <CentralData>
        <SMData>
            <CentralSDItem>
                <ControlData>6789</ControlData>
            </CentralSDItem>
        </SMData>
    </CentralData>
</SMObjInfo>
Run Code Online (Sandbox Code Playgroud)

我写了一篇关于修改功能的博客文章,以及SQLServerScience.com 上的更多示例


Mik*_*son 9

如果您在表中有 XML,您应该使用 UPDATE 而不是 SET 并且您可以使用WITH XMLNAMESPACES将名称空间声明放在 XML_DML 表达式之外

with xmlnamespaces(default 'DataService/1.0.0.0')
update DataImpTable
set serviceData.modify('replace value of (/SMObjInfo/CentralData/SMData/CentralSDItem
                                            /ControlData/text())[1] with "9876"')
where identifier=5
Run Code Online (Sandbox Code Playgroud)