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必要があるためです。truefrac

次のSQLは、更新が必要なXMLアイテムノードを識別します。

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

itemこれらのノードを修正するために更新を行いたいのですが、で識別される要素を変更する方法がわかりません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)

ただし、これは機能していません。「'modify'の近くの構文が正しくありません」というエラーが表示されます。

これはこの方法で行うことができますか?

代わりに、xml列で文字列の置換を行うこともできますが、それが少し微妙ではないのは好きではありません(実際の文章題で問題が発生しないとは確信していません)。

4

1 に答える 1

4

一度に複数の場所で1つのXMLインスタンスを更新することはできないため、完了するまでループで更新を行う必要があります。

http://msdn.microsoft.com/en-us/library/ms190675.aspxから「式1:値が更新されるノードを識別します。単一のノードのみを識別する必要があります。」

-- 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 に答える