5

我在 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>

我设法用以下内容更新了该列:

   -----just update the name to the id)----
   UPDATE tbl1
   SET [myXml].modify('replace value of (/Bands/Band/Name/text())[1]
   with sql:column("id")')

一切都好。

问题 #1

如何使用此查询将值更新为id+"lalala"

   UPDATE tbl1
   SET [myXml].modify('replace value of (/Bands/Band/Name/text())[1]
   with sql:column("id") + "lalala"')

错误 = XQuery [tbl1.myXml.modify()]: '+' 的参数必须是单个数字原始类型

问题 #1

假设我不想更新第一条记录 ( [1]) ,但我只想udpate(与上面相同的更新) where 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...]')

这是网上的sql

4

2 回答 2

6

如果要连接字符串,则应使用concat,如果id在您的情况下是整数,则需要将其转换为concat函数中的字符串。

在 where 子句中您可以过滤要更新的表行,您不能在 XML 中指定要更新的节点。这必须在 xquery 表达式中完成。但是,您可以在 where 子句中使用exists来过滤掉真正需要更新的行。

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
于 2012-11-28T07:06:07.147 回答
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")');

注意:您是否意识到这只会更新第一个乐队的名称,而不是所有乐队的名称?

第二季度:

你不能。特别是因为(/Bands/Band[Score<4]/Name/text())[1](我改为<)专门针对问题中示例 xml 中的门带。另一方面,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

因为 xml 中至少有一个 Band 的分数 < 4,所以 XML 得到更新。 但是,因为xml.modify仅在第一场比赛中有效,所以第一个乐队的名称会更新,而不是与得分过滤器匹配的乐队名称。

于 2012-11-28T00:59:20.153 回答