sql 查询以更新存储在列中的 xml 节点

sql query to update xml node stored in a column

我正在开发一个项目,我正在使用一个 table,其中 xml 数据存储在其中一个 column.I 中,我正在尝试更新我的整个 xml基于 xml_id 的节点和 xml 节点的位置,但我无法执行 that.I 尝试了以下查询,但它只更新了 xml 节点的值,而不是整个 [=节点的 36=]。

Table结构

查询以更新 xml 节点的值

update tblCCBT_Step_Page_Text_Xml
set Xml_XmlData.modify('replace value of (/page/*[position()=1]/text())[1] 
                with "test value"')where xml_id = 101

所以现在我尝试了以下查询来更新整个内部节点

update tblCCBT_Step_Page_Text_Xml
set Xml_XmlData.modify('replace value of (/page/*[position()=1]/text())[1] 
                with "<testnode>test value</testnode>"') where xml_id = 101

但是我在尝试执行此操作时遇到错误

Msg 9306, Level 16, State 1, Line 2
XQuery [tblCCBT_Step_Page_Text_Xml.Xml_XmlData.modify()]: The target of 'replace value of' cannot be a union type, found '(element(*,xdt:untyped) | comment | processing-instruction | text) ?'.

这是我的xml存储在列

<page name="page0" identifier="ff-102-101-101">
     <backBut>test value</backBut>
     <printBut>Print</printBut>
     <quiz1>Click on the circle that best describes your</quiz1>
     <quiz2>Continue</quiz2>
     <quiz3>Finish</quiz3>
     <quiz4>You are now on questions </quiz4>
     <quiz5>out of</quiz5>
     <quiz6>Please answer each question before continuing.</quiz6>
 </page>

现在在上面 xml 我正在尝试替换 -

<backBut>test value</backBut> with <testnode>test value</testnode>

请建议如何实现这一点。谢谢

您可以使用 insert/delete 方法。

你的代码在 SQL2008R2 上没有为我抛出任何错误。 但它也没有给出预期的结果。

该语句导致替换节点的文本值,而不是替换节点本身,如下所示。

<page name="page0" identifier="ff-102-101-101">
  <backBut>&lt;testnode&gt;test value&lt;/testnode&gt;</backBut>
  <printBut>Print</printBut>
  <quiz1>Click on the circle that best describes your</quiz1>
  <quiz2>Continue</quiz2>
  <quiz3>Finish</quiz3>
  <quiz4>You are now on questions </quiz4>
  <quiz5>out of</quiz5>
  <quiz6>Please answer each question before continuing.</quiz6>
</page>

你可以通过 insert/delete:

首先插入新节点:

UPDATE tblCCBT_Step_Page_Text_Xml
SET Xml_XmlData.modify('insert <testnode>test value</testnode> into /page[1]')
WHERE xml_id = 101

然后干脆删除旧节点:

UPDATE tblCCBT_Step_Page_Text_Xml
SET Xml_XmlData.modify('delete (/page/backBut)[1]')
WHERE xml_id =101

不敢相信我做到了:)

declare @t table (
    Id int,
    XMLData xml
);

insert into @t (Id, XMLData)
values
    (101, N'<page name="page0" identifier="ff-102-101-101">
     <backBut>test value</backBut>
     <printBut>Print</printBut>
     <quiz1>Click on the circle that best describes your</quiz1>
     <quiz2>Continue</quiz2>
     <quiz3>Finish</quiz3>
     <quiz4>You are now on questions </quiz4>
     <quiz5>out of</quiz5>
     <quiz6>Please answer each question before continuing.</quiz6>
 </page>');

-- Before modification
select * from @t;

update t set XMLData = nt.ModXML
from @t t
    inner join (
        select t2.Id, t2.XMLData.query('
element page {
    /page/@*,
    for $n in /page/*
    return
        if (local-name($n) = "backBut") then
            <testnode>test value</testnode>
        else
            $n
}') as [ModXML]
        from @t t2
    ) nt on t.Id = nt.Id
where t.Id = 101;

-- After modification
select * from @t;

如您所见,严格来说,这不是 XML 更新 - 我正在替换整个 XML 字段的内容。此外,如果结构更复杂,它可能会停止工作。而且,性能也可能是一个问题。