SQL XML列 - 基于其他节点更新子节点值

时间:2015-01-20 20:32:24

标签: sql sql-server sql-server-2008-r2 sqlxml

我不习惯在sql列中使用xml,并且有关于更新该列内容的问题。

我有一个表(TableXML),其中包含以下xml层次结构的列(ColumnXML):Xml/Content/Queues/list/Item/

每个项目都有一个/Name,一个PluginsProperties/Item

列表

并且其他每个项目都有/keyvalue

例如:

<Xml>
    <Content Tr="1">
        <Queues Tr="12">
            <list Tr="13">
                <Item Tr="14">
                    <Name Tr="2">Data Load Exception</Name>
                    <PluginProperties Tr="15">
                        <Item Tr="16">
                            <key Tr="2">MSMQQueueType</key>
                            <value Tr="2">PrivateQueue</value>
                        </Item>
                        ...........more items
                    </PluginProperties>
                </Item>
                ...........more items
            </list>
        </Queues>
    </Content>
</Xml>

我想做什么:

/Xml/Content/Queues/list/Item/PluginProperties/Item/value代码的值更新为PublicQueue

/Xml/Content/Queues/list/Item/PluginProperties/Item/keyMSMQQueueType

/Xml/Content/Queues/list/Item/NameData Load Exception

除了名称为Data Load Exception的“队列项目”之外,不应该受到影响,除了具有键MSMQQueueType的项目之外,“PluginProperties项目”不会受到影响。

谢谢! =)

1 个答案:

答案 0 :(得分:1)

您可以使用replace value of子句来执行此操作

如果它是单个节点,则可以使用下面的单个语句完成

     update TableXML
     set columnXML.modify('
            replace value of    ((/Xml/Content/Queues/list/Item/PluginProperties/Item/value)[1]/text())[1] with ''PublicQueue''')
 where columnXML.value('((/Xml/Content/Queues/list/Item/PluginProperties/Item/key)[1]/text())[1]','varchar(50)') = 'MSMQQueueType' 
  and columnXML.value('((/Xml/Content/Queues/list/Item/Name)[1]/text())[1]','varchar(50)') = 'Data Load Exception' 

由于存在许多节点,我们需要获取节点的数量并使用while循环来完成,如下所示

declare @elements int

select @elements = ISNULL(columnXML.value('count(/Xml/Content/Queues/list/Item/PluginProperties/Item)', 'int'),0)
from TableXML


while @elements > 0 
begin

  update TableXML
  set columnXML.modify
    ('replace value of ((/Xml/Content/Queues/list/Item/PluginProperties/Item/value)[sql:variable("@elements")]/text())[1]
      with ''PublicQueue''')
  where columnXML.value('((/Xml/Content/Queues/list/Item/PluginProperties/Item/key)[sql:variable("@elements")]/text())[1]','varchar(50)') = 'MSMQQueueType' 
  and columnXML.value('((/Xml/Content/Queues/list/Item/Name)[sql:variable("@elements")]/text())[1]','varchar(50)') = 'Data Load Exception' 


  set @elements = @elements - 1
end