XML 文書の部分更新

XML 列の XML 文書の一部を更新するには、組み込みスカラー関数 XMLMODIFY を指定した SQL UPDATE ステートメントを使用します。

変更の開始XMLMODIFY 関数は、以下のいずれかのタイプの式を指定します。変更の終わり

変更の開始
  • ノードの挿入、ノードの削除、ノードの置換、または XML 列に格納されている XML 文書のノード値の置換に使用できる、単一の basic updating expression
  • 複数の基本的な更新式が含まれる updating expression。 この更新式は、次のいずれかの式を使用できます。
    • シーケンス式
    • return 節に更新式を含む FLWOR 式
    • then または else 節に更新式を含む条件式
変更の終わり

XMLMODIFY を使用して XML 文書の一部を更新するには、この XML 文書が入っている列で XML バージョンがサポートされている必要があります。

基本更新式のタイプを以下に示します。

挿入式
1 つ以上のノードのコピーをノード・シーケンス内の指定された位置に挿入します。
置換式
既存のノードをゼロ以上のノードの新規シーケンスで置き換えるか、ノードの ID の保存中にノードの値を置換します。
削除式
0 または 1 つ以上のノードをノード・シーケンスから削除します。

注文書 ID (POID) が 5000 の purchaseOrder 文書の 2 番目の shipTo ノードを置換するとします。この文書は次のようになります。

<ipo:purchaseOrder
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:ipo="http://www.example.com/IPO"
   orderDate="2008-12-01">
  <shipTo exportCode="1" xsi:type="ipo:UKAddress">
    <name>Helen Zoe</name>
    <street>55 Eden Street</street>
    <city>San Jose</city>
    <state>CA</state>
    <postcode>CB1 1JR</postcode>
  </shipTo>
  <shipTo exportCode="1" xsi:type="ipo:UKAddress">
    <name>Joe Lee</name>
    <street>66 University Avenue</street>
    <city>Palo Alto</city>
    <state>CA</state>
    <postcode>CB1 1JR</postcode>
  </shipTo>
  <billTo xsi:type="ipo:USAddress">
    <name>Robert Smith</name>
    <street>8 Oak Avenue</street>
    <city>Old Town</city>
    <state>PA</state>
    <zip>95819</zip>
  </billTo>
  <items>
    <item partNum="833-AA">
      <productName>Lapis necklace</productName>
      <quantity>1</quantity>
      <USPrice>99.95</USPrice>
      <ipo:comment>Want this for the holidays!</ipo:comment>
      <shipDate>2008-12-05</shipDate>
    </item>
    <item partNum="945-ZG">
      <productName>Sapphire Bracelet</productName>
      <quantity>2</quantity>
      <USPrice>178.99</USPrice>
      <shipDate>2009-01-03</shipDate>
    </item>
  </items>
</ipo:purchaseOrder>

shipTo ノードを置換するには、次に示すような SQL UPDATE ステートメントを使用できます。

UPDATE PURCHASEORDER
 SET INFO = XMLMODIFY(
  'declare namespace ipo="http://www.example.com/IPO";
  replace node /ipo:purchaseOrder/shipTo[name="Joe Lee"]
  with $x', XMLPARSE(
   '<shipTo exportCode="1" xsi:type="ipo:USAddress">
    <name>Joe Lee</name>
    <street>555 Quarry Road</street>
    <city>Palo Alto</city>
    <state/>CA
    <postcode>94304</postcode>
    </shipTo>') AS "x") 
 WHERE POID=5000

このステートメントの実行後、PORDER 列の文書の内容は次のようになります。

<ipo:purchaseOrder
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:ipo="http://www.example.com/IPO"
   orderDate="2008-12-01">
  <shipTo exportCode="1" xsi:type="ipo:UKAddress">
    <name>Helen Zoe</name>
    <street>55 Eden Street</street>
    <city>San Jose</city>
    <state>CA</state>
    <postcode>CB1 1JR</postcode>
  </shipTo>
  <shipTo exportCode="1" xsi:type="ipo:USAddress">
   <name>Joe Lee</name>
   <street>555 Quarry Road</street>
   <city>Palo Alto</city>
   <state>CA</state>
   <postcode>94304</postcode>
  </shipTo>
  <billTo xsi:type="ipo:USAddress">
    <name>Robert Smith</name>
    <street>505 First Street</street>
    <city>Old Town</city>
    <state>PA</state>
    <zip>95819</zip>
  </billTo>
  <items>
    <item partNum="833-AA">
      <productName>Lapis necklace</productName>
      <quantity>1</quantity>
      <USPrice>99.95</USPrice>
      <ipo:comment>Want this for the holidays!</ipo:comment>
      <shipDate>2008-12-05</shipDate>
    </item>
    <item partNum="945-ZG">
      <productName>Sapphire Bracelet</productName>
      <quantity>2</quantity>
      <USPrice>178.99</USPrice>
      <shipDate>2009-01-03</shipDate>
    </item>
  </items>
</ipo:purchaseOrder>
変更の開始

以下の文書で、単一の XMLMODIFY 呼び出し内で次のような変更を行うとします。

  • パーツ・ナンバー 872-AA の項目で、数量を 2 に変更します
  • パーツ・ナンバー 945- ZG の項目を削除します
<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>149.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>178.99</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>

変更を行うには、以下のような 2 つの基本的な更新式を使用して XMLMODIFY を呼び出します。

UPDATE PURCHASEORDER
 SET PORDER = XMLMODIFY(
 'declare namespace ipo="http://www.example.com/IPO";
  replace value of node /ipo:purchaseOrder/items/item[@partNum="872-AA"]/quantity
  with xs:integer(2),
  delete node /ipo:purchaseOrder/items/item[@partNum="945-ZG"]’);

このステートメントの実行後、文書の内容は次のようになります。

<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>2</quantity>
   <USPrice>149.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
</items>
</ipo:purchaseOrder>
変更の終わり
変更の開始

以下の文書では、単一の XMLMODIFY 呼び出し内で各項目の価格を 10% 上げるとします。

<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>149.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>178.99</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>

変更を行うには、以下のように FLWOR 式を使用して XMLMODIFY を呼び出します。

UPDATE PURCHASEORDER
 SET PORDER = XMLMODIFY(
  'declare namespace ipo="http://www.example.com/IPO";
   for $i in /ipo:purchaseOrder/items/item
    let $p := $i/USPrice
     where xs:decimal($p)>0
   return
    replace value of node $p with $p *1.1’);

このステートメントの実行後、文書の内容は次のようになります。

<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>164.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>196.89</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>
変更の終わり
変更の開始

以下の文書で、単一の XMLMODIFY 呼び出し内で次のような変更を行うとします。
  • 数量が複数である項目の場合、価格を 10% 下げます。
  • 数量が 1 である項目の場合、価格を 5% 上げます。
<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>149.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>178.99</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>

変更を行うには、以下のように条件式を使用して XMLMODIFY を呼び出します。

UPDATE PURCHASEORDER
 SET PORDER = XMLMODIFY(
  'declare namespace ipo="http://www.example.com/IPO";
   for $i in /ipo:purchaseOrder/items/item
    let $p := $i/USPrice
    let $q := $i/quantity
   where xs:decimal($p)>0 and xs:integer($q)>0
   return
   (
    if (xs:integer($q) > 1) then
     replace value of node $p with $p *0.9
    else
     replace value of node $p with $p *1.05
   )’
 );

このステートメントの実行後、文書の内容は次のようになります。

<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>157.49</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>161.09</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>
変更の終わり