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>