SQL XML列-根据其他节点更新子节点值

SQL XML column - update child node value based on other nodes

我不习惯在 sql 列中使用 xml,对更新该列的内容有疑问。

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

每个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 的 "Queue item" 之外,没有 "Queue item" 应该受到影响,除了密钥为 MSMQQueueType 的 "PluginProperties item" 之外,没有 "PluginProperties item" 应该受到影响。

谢谢! =)

你可以使用 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