简体   繁体   English

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

[英]sql query to update xml node stored in a column

I am working on a project where I am using a table which have xml data stored in one of its column.I am trying to update my entire xml node based on xml_id and position of xml node but I am unable to do that.I tried the following query but its only updating the value of xml node not the entire key/value of node. 我在一个项目中工作,我正在使用一个表,该表的xml数据存储在其列之一中。我试图根据xml_id和xml节点的位置更新我的整个xml节点,但是我无法做到这一点。以下查询,但仅更新xml节点的值,而不更新节点的整个键/值。

Table structure 表结构

在此处输入图片说明

Query to update value of xml node 查询更新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

So now I tried the following query to update entire internal node 所以现在我尝试了以下查询来更新整个内部节点

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

But I am getting error while trying to do this 但是在尝试执行此操作时出现错误

Msg 9306, Level 16, State 1, Line 2 消息9306,第16级,状态1,第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) ?'. XQuery [tblCCBT_Step_Page_Text_Xml.Xml_XmlData.modify()]:“替换值”的目标不能是联合类型,找到了“(element(*,xdt:untyped)|注释|处理指令|文本)?”。

This is my xml stored in the column 这是我存储在列中的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>

Now in above xml I am trying to replace - 现在在上述xml中,我尝试替换-

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

Please suggest how to achieve this. 请建议如何实现。 Thanks 谢谢

You could use an insert/delete approach. 您可以使用插入/删除方法。

Your code did not throw any error for me on SQL2008R2. 您的代码在SQL2008R2上对我没有引发任何错误。 But it did NOT give the desired result either. 但是它也没有给出预期的结果。

The statement resulted in replacing the text value of the node, not in replacing the node itself, as you can see below. 该语句导致替换了节点的文本值,而不是替换了节点本身,如下所示。

<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>

You could achieve it via insert/delete: 您可以通过插入/删除来实现:

First insert the new node: 首先插入新节点:

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

Then simply delete the old node: 然后只需删除旧节点:

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

Can't believe I did it :) 不敢相信我做到了:)

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;

As you can see, it's not an XML update, strictly speaking - I am replacing the contents of the entire XML field. 如您所见,严格来说,它不是XML更新-我要替换整个XML字段的内容。 Also, it might stop working in case of more complex structure. 另外,如果结构更复杂,它可能会停止工作。 And, well, performance can be an issue, too. 而且,性能也是一个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM