Roy*_*mir 5 xml sql-server xquery sql-server-2008
我在XML列中有一个简单的xml
<Bands>
<Band>
<Name>beatles</Name>
<Num>4</Num>
<Score>5</Score>
</Band>
<Band>
<Name>doors</Name>
<Num>4</Num>
<Score>3</Score>
</Band>
</Bands>
Run Code Online (Sandbox Code Playgroud)
我已设法更新列:
-----just update the name to the id)----
UPDATE tbl1
SET [myXml].modify('replace value of (/Bands/Band/Name/text())[1]
with sql:column("id")')
Run Code Online (Sandbox Code Playgroud)
一切都很好.
问题#1
如何使用此查询将值更新为id+"lalala":
UPDATE tbl1
SET [myXml].modify('replace value of (/Bands/Band/Name/text())[1]
with sql:column("id") + "lalala"')
Run Code Online (Sandbox Code Playgroud)
Error = XQuery [tbl1.myXml.modify()]:'+'的参数必须是单个数字基元类型
问题#1
假设我不想更新第一条记录([1]),但我想udpate(仅与上面相同的更新)只在哪里score>4.
我可以在xpath中写道:
replace value of (/Bands/Band[Score>4]/Name/text())[1]
但我不想在Xpath中这样做.是不是有一个正常的方式来做一个Where条款?
就像是 :
UPDATE tbl1
SET [myXml].modify('replace value of (/Bands/Band/Name/text())[1]
with sql:column("id") where [...score>4...]')
Run Code Online (Sandbox Code Playgroud)
如果你想连接字符串,你应该使用concat,如果id在你的情况下是一个整数,你需要将它转换为concat函数中的字符串.
在where子句中,您可以过滤要更新的表的行,您无法指定要在XML中更新的节点.这必须在xquery表达式中完成.但是,您可以使用存在的where子句中筛选出真正需要更新的行.
update tbl1
set myXml.modify('replace value of (/Bands/Band[Score > 4]/Name/text())[1]
with concat(string(sql:column("id")), "lalalala")')
where myXml.exist('/Bands/Band[Score > 4]') = 1
Run Code Online (Sandbox Code Playgroud)
Q1:
;with t as (select convert(varchar(10),id) + 'lalala' id2, * from #tbl1)
UPDATE t
SET [myXml].modify('replace value of (/Bands/Band/Name/text())[1]
with sql:column("id2")');
Run Code Online (Sandbox Code Playgroud)
注意:您是否意识到这只更新了第一个乐队名称的名称,而不是所有乐队?
第二季度:
你不能.特别是因为(/Bands/Band[Score<4]/Name/text())[1](我改为<)专门针对你的示例xml问题中的门Band.另一方面,WHERE子句将跨XML工作,而不是路径中的特定级别.例如一个非常错误的解释:
;with t as (
select a.*, n.m.value('.','int') Score
from #tbl1 a
cross apply myXml.nodes('/Bands/Band/Score') n(m) -- assume singular
)
UPDATE t
SET [myXml].modify('replace value of (/Bands/Band/Name/text())[1]
with sql:column("id")')
where Score < 4
Run Code Online (Sandbox Code Playgroud)
因为xml中至少有一个得分<4的Band,所以XML会更新. 但是,因为xml.modify只在第一场比赛中使用ONCE,第一个乐队的名字会更新,而不是与乐谱过滤器匹配的名称.