2

我遇到了一些存储在数据库 XML 列中的值的数据问题。我已将问题重现为以下示例:

设置脚本:

create table XMLTest
(
    [XML] xml
)

--A row with two duff entries
insert XMLTest values ('
    <root>
        <item>
            <flag>false</flag>
            <frac>0.5</frac>
        </item>
        <item>
            <flag>false</flag>
            <frac>0</frac>
        </item>
        <item>
            <flag>false</flag>
            <frac>0.5</frac>
        </item>     
        <item>
            <flag>true</flag>
            <frac>0.5</frac>
        </item>
    </root>
    ')

在 XML 部分中,不正确的条目是那些具有<flag>false</flag>并且<frac>0.5</frac>flag应该是true非零frac值的条目。

以下 SQL 标识需要更新的 XML 项节点:

select
    i.query('.')
from
    XMLTest
    cross apply xml.nodes('root/item[flag="false" and frac > 0]') x(i)

我想进行更新以更正这些节点,但我看不到如何修改item由 a 标识的元素cross apply。我看到更新看起来像这样:

 update t
    set
        x.i.modify('replace value of (flag/text())[1] with "true"')
    from
        XMLTest t
        cross apply xml.nodes('root/item[flag="false" and frac > 0]') x(i)

但是这不起作用:我收到错误“'修改'附近的语法不正确”。

可以通过这种方法完成吗?

我知道另一种方法是在 xml 列上进行字符串替换,但我不喜欢这样有点含糊(而且我不相信它不会破坏我的真实问题)

4

1 回答 1

4

一次在多个位置更新一个 XML 实例是不可能的,因此您必须循环进行更新,直到完成。

来自http://msdn.microsoft.com/en-us/library/ms190675.aspx “Expression1:标识要更新其值的节点。它必须仅标识单个节点。”

-- While there are rows that needs to be updated
while exists(select *
             from XMLTest
             where [XML].exist('root/item[flag="false" and frac > 0]') = 1)
begin
  -- Update the first occurence in each XML instance 
  update XMLTest set
    [XML].modify('replace value of (root/item[flag="false" and frac > 0]/flag/text())[1] with "true"')
  where xml.exist('root/item[flag="false" and frac > 0]') = 1
end             
于 2011-07-22T17:22:58.600 回答