使用XQUERY更新SQL Server xml列?

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)

这是在线sql

Mik*_*son 6

如果你想连接字符串,你应该使用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)


Ric*_*iwi 5

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,第一个乐队的名字会更新,而不是与乐谱过滤器匹配的名称.