Sql server 如何修改SQL XML列中的节点内容?

Sql server 如何修改SQL XML列中的节点内容?,sql-server,xml,Sql Server,Xml,我将一些数据存储在表中的SQLServerXML数据列中。它用于配置HTML内容(作为电子邮件发送),工作正常。然而,我现在想更改一些数据,但我似乎找不到正确的咒语来实现我想要的比特 以以下为例 declare @s1 varchar(max); declare @s2 varchar(max); declare @s3 varchar(max); -- rough approximation of my data set @s1 = '<email sender="bob">&l

我将一些数据存储在表中的SQLServerXML数据列中。它用于配置HTML内容(作为电子邮件发送),工作正常。然而,我现在想更改一些数据,但我似乎找不到正确的咒语来实现我想要的比特

以以下为例

declare @s1 varchar(max);
declare @s2 varchar(max);
declare @s3 varchar(max);

-- rough approximation of my data
set @s1 = '<email sender="bob"><html><body><table><tbody><tr><td><b>'
set @s2 = '</b></td></tr><tr><td><b>'
set @s3 = '</b></td></tr></tbody></table></body></html></email>'

declare @t table (id int, data xml)

insert into @t values (1, @s1 + 'Hello World' + @s2 + 'Goodbye cruel world' + @s3)
insert into @t values (2, @s1 + 'Hello World' + @s2 + 'I''m leaving you today' + @s3)
insert into @t values (3, @s1 + 'Hello World' + @s2 + 'Goodbye, goodbye, goodbye' + @s3)

select data from @t

update @t -- change sender to "fred"
set data.modify('replace value of (/email/@sender)[1] with "fred"')

select data from @t

select data,x.nd.value('b[1]','varchar(max)') -- find the "hello world" bits
from @t
cross apply data.nodes('email/html/body/table/tbody/tr/td') as x(nd)
where x.nd.value('b[1]','varchar(max)') = 'Hello World'
谢谢。

几乎:)编辑中的示例更新了第一个
email/html/body/table/tbody/tr/td/b
,但WHERE子句查找任何
email/html/body/table/tbody/tr/td
。因此,如果你有一封电子邮件,比如说,有两封
tr
,而第二封与过滤器匹配,你仍然会更新第一封。例如

 insert into @t values (4, '<email sender="bob"><html><body><table><tbody>
   <tr><td><b>Ciao mondo!</b></td></tr><tr><td><b>Goodbye, goodbye, goodbye</b></td></tr>
   <tr><td><b>Hello World</b></td></tr><tr><td><b>Can''t get rid of me!</b></td></tr>
   </tbody></table></body></html></email>');
这将更加正确,但它必须重复运行,因为一次只能修改一个XML元素(即,如果两个
tr
拥有Hello World,那么修改将只更新第一个)


也许所有这些观点对你来说都是学术性的,因为你的第一次更新很可能成功了。但供将来参考。顺便说一句,了解如何使用,它们非常有帮助。

谢谢你的提示。XPath过滤器。
 insert into @t values (4, '<email sender="bob"><html><body><table><tbody>
   <tr><td><b>Ciao mondo!</b></td></tr><tr><td><b>Goodbye, goodbye, goodbye</b></td></tr>
   <tr><td><b>Hello World</b></td></tr><tr><td><b>Can''t get rid of me!</b></td></tr>
   </tbody></table></body></html></email>');
update @t
set data.modify('replace value of (email/html/body/table/tbody/tr/td/b[.="Hello World"]/text())[1] with "bonjour monde"')
from @t
where data.exist('email/html/body/table/tbody/tr/td/b[.="Hello World"]') = 1;