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
并且这些其他项目中的每一个都有一个 /key
和 value
例如:
<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/key
是 MSMQQueueType
而 /Xml/Content/Queues/list/Item/Name
是 Data 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
我不习惯在 sql 列中使用 xml,对更新该列的内容有疑问。
我有一个 table (TableXML
),其列 (ColumnXML
) 包含以下 xml 层次结构:Xml/Content/Queues/list/Item/
每个Item都有一个/Name
,一个列表PluginsProperties/Item
并且这些其他项目中的每一个都有一个 /key
和 value
例如:
<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/key
是 MSMQQueueType
而 /Xml/Content/Queues/list/Item/Name
是 Data 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