假设我有一个带有XML列的数据库表.
对于每一行,XML的结构相同(或类似),但标签的内容不同.
结构看起来像这样:
<Parent1>
<Parent2>
<Child>
test 1
</Child>
</Parent2>
<Parent2>
<Child>
test 2
</Child>
</Parent2>
</Parent1>
Run Code Online (Sandbox Code Playgroud)
我想对结构中的每个'Child'节点进行一些处理,并用结果更新它们.
例如,我想用'something'替换'test'这个词.
所以我不希望两个子节点最终都包含'1号'.
相反,我希望第一个子节点包含'something 1',第二个子节点包含'something 2'.
我可以写下面,靶向单在时间节点:
DECLARE @replacement NVARCHAR(4000) = 'something 1'
UPDATE MyTable
SET MyXMLField.modify('replace value of (Parent1[1]/Parent2[1]/Child[1]/text())[1] with sql:variable("@replacement")')
WHERE Id = 1
Run Code Online (Sandbox Code Playgroud)
但是,是否可以编写一个T-SQL语句来处理多个节点,由XPath匹配,并根据一个函数的结果单独更新每个节点?
你必须在循环中,一次一个节点.
declare @MyTable table(Id int, MyXMLField xml)
insert into @MyTable values
(1, '<Parent1>
<Parent2>
<Child>test 1</Child>
</Parent2>
<Parent2>
<Child>test 2</Child>
</Parent2>
</Parent1>')
declare @replacement nvarchar(4000) = 'something 1'
declare @Parent2Count int
select @Parent2Count = MyXMLField.value('count(/Parent1/Parent2)', 'int')
from @MyTable
where Id = 1
declare @Node int
set @Node = 1
while @Node <= @Parent2Count
begin
update @MyTable set
MyXMLField.modify('replace value of
(/Parent1/Parent2[sql:variable("@Node")]/Child/text())[1]
with sql:variable("@replacement")')
where Id = 1
set @Node = @Node + 1
end
Run Code Online (Sandbox Code Playgroud)