1

我正在做一个项目,我正在使用一个表,其中一个列中存储了 xml 数据。我正在尝试根据 xml_id 和 xml 节点的位置更新我的整个 xml 节点,但我无法做到这一点。我试过了以下查询,但它只更新 xml 节点的值,而不是节点的整个键/值。

表结构

在此处输入图像描述

查询更新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

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

消息 9306,级别 16,状态 1,第 2 行
XQuery [tblCCBT_Step_Page_Text_Xml.Xml_XmlData.modify()]:'replace value of' 的目标不能是联合类型,找到 '(element(*,xdt:untyped) | 注释 |处理指令|文本)?'。

这是我存储在列中的 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>

请建议如何实现这一目标。谢谢

4

2 回答 2

4

您可以使用插入/删除方法。

您的代码在 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>

您可以通过插入/删除来实现它:

首先插入新节点:

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
于 2015-04-15T04:12:19.267 回答
1

不敢相信我做到了:)

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 字段的内容。此外,如果结构更复杂,它可能会停止工作。而且,性能也可能是一个问题。

于 2015-04-15T07:29:35.080 回答