2011-06-28 22 views
1

存在しない場合のXQueryのパスを作成します:DB2データベースのXML列に保存されているそれは私がこのようなXML構造を有する

<data> 
    <a> 
    <element name="aName">123</element> 
    <element name="xyz">foobar</element> 
    </a> 
    <b> 
    <element name="aName">foo</element> 
    <element name="otherName">bar</element> 
    </b> 
</data> 

を。/a/element/@ name内は一意であり、/ b/element/@ nameは一意です。

ここで、どちらかに新しい要素タグを挿入します。同じ名前属性を持つ要素が既に存在する場合、その要素を置き換えたい(要素タグの順序は関係ありません)。

update mytable set myXmlColumn=xmlquery('copy $new := $old modify 
    (
    do delete $new/data/a/element[@name=$newName], 
    do insert $insert as last into $new/data/a 
) return $new' 
    passing 
    'aName' as "newName", 
    xmlparse(document '<element name="aName">aaa</element>') as "insert"), 
    myXmlColumn as "old" 
) where id=123 

これは、それが存在する場合、同じ名前を持つ別の要素を削除し、すべての権利新しい要素を挿入します。私はそのようなこれをしませんでした。しかし、タグがまだ存在しない場合でも(空のタグを作成して新しい要素を追加する必要があります)、myXmlColumnが以前nullだった場合でも動作するはずです。

私は解決策を見いだしましたが、それは私にはかなり面白いと感じました。通過セクションでは、coalesce(myXmlColumn,xmlparse(document '<data><a /></data>'))と書くことができ、myXmlColumnがnullの場合にステートメントを動作させます。しかし、もしそれがnullではないが、ただ欠けているのであれば?

答えて

1

解決策が見つかったが、それでもまだ気分は悪かった。よりエレガントな解決策がある場合、私はあなたが存在するノードに応じて、XMLの異なる量を追加しますあなたのXQuery式でIF-THENロジックを追加することができます

update mytable set myXmlColumn=xmlquery('copy $xml := (if (not($xml/data/a)) then transform copy $xml := $xml modify (do insert <a/> as last into $xml/data) return $xml else $xml) modify 
    (
    do delete $xml/data/a/element[@name=$newName], 
    do insert $insert as last into $xml/data/a 
) return $xml' 
    passing 
    'aName' as "newName", 
    xmlparse(document '<element name="aName">aaa</element>') as "insert"), 
    COALESCE(myXmlColumn, xmlparse(document '<data/>')) as "xml" 
) where id=123 
0

...だろうか。この方法では、/ data/a/data/a/data/a/data/a/dataのようなほとんどすべての状況を処理できるようにプログラムできるので、柔軟性が最も高くなります。ルートドキュメント要素が<data>でないときに何をすべきかを決めることさえできます。

COALESCE()については、私はそれが好きで、あなたが説明した条件のための価値ある回避策だと考えています。

関連する問題