プライマリ・コンテンツに移動
Oracle® XML DB開発者ガイド
12cリリース1 (12.1)
B71282-04
目次へ移動
目次
索引へ移動
索引

前
次

C XMLデータを更新するための非推奨の関数

Oracle Database 12c リリース1 (12.1.0.1)から非推奨になった、XMLデータを更新するためのOracle SQL関数について説明します。XMLデータを更新するには、かわりにXQuery Updateを使用してください(XQueryとOracle XML DBを参照)。

C.1 XMLデータを更新するためのOracle関数のXQuery Updateへの移行

XQuery Update Facility 1.0勧告は、Oracle Database 12cリリース1 (12.1.0.1)からOracle XML DBでサポートされるようになりました。これよりも前のリリースでXMLデータを更新するには、Oracle固有のSQL関数appendChildXMLdeleteXMLinsertChildXMLinsertchildXMLafterinsertChildXMLbeforeinsertXMLafterinsertXMLbeforeおよびupdateXMLを問合せで必ず使用する必要がありました。

これらの関数については、この付録の別の項で詳しく説明します。

これらの関数を使用しているレガシー・コードがある場合は、そのコードを移行してXQuery Updateを使用することをお薦めします。この項では、問合せで使用されているOracle固有のXML更新関数を置き換える場合に使用できるXQuery Updateの構造体について説明します。

表C-1は、Oracle固有の更新のSQL関数を使用した一般的な問合せから、XQuery Updateを使用した問合せへのマッピングを示しています。

XQuery Updateの構造体renameおよびinsert as first intoには、同等のOracle固有の関数はありません。

また、ターゲットのXPath式が複数のノードと一致する場合、Oracle更新関数は該当するすべてのノードに作用しますが、XQuery Update関数ではこの場合、エラーが発生します。XQuery Updateを使用して複数のノードに作用するには、明示的な繰返し(for式)を使用する必要があります。

表C-1 Oracle固有のXML更新問合せのXQuery Updateへの移行

元の式 置換後の式
-- Insert a node as the last child of a node.
UPDATE warehouses SET warehouse_spec =
  appendChildXML(
    warehouse_spec,
    '/Warehouse/Parking',
    XMLType('<Spaces>250</Spaces>'));
-- Insert a node as the last child of a node.
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := . modify insert node 
            <Spaces>250</Spaces>
            as last into $tmp/Warehouse/Parking
            return $tmp'
           PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Delete a node.
UPDATE warehouses SET warehouse_spec =
  deleteXML(value(po), '/Warehouse/VClearance');
-- Delete a node.
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := . modify delete node
            $tmp/Warehouse/VClearance return $tmp'
           PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Insert a node as a child of a node.
UPDATE warehouses SET warehouse_spec =
  insertChildXML(
    warehouse_spec,
    '/Warehouse/Parking',
    'Spaces',
    XMLType('<Spaces>300</Spaces>');
-- Insert a node as a child of a node.
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := . modify insert node
            <Spaces>300</Spaces>
            into $tmp/Warehouse/Parking
            return $tmp'
           PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Insert a node before a node.
UPDATE warehouses SET warehouse_spec = 
  insertXMLbefore(
    warehouse_spec, 
    '/Warehouse/RailAccess', 
    XMLType('<SkyAccess>N</SkyAccess>');
-- Insert a node before a node.
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := . modify insert node
            <SkyAccess>N</SkyAccess>
            before $tmp/Warehouse/RailAccess 
            return $tmp'
           PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Insert a node after a node.
UPDATE warehouses SET warehouse_spec = 
  insertXMLafter(
    warehouse_spec,
    '/Warehouse/RailAccess', 
    XMLType('<SkyAccess>N</SkyAccess>');
-- Insert a node after a node.
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := . modify insert node 
            <SkyAccess>N</SkyAccess>
            after $tmp/Warehouse/RailAccess 
            return $tmp'
           PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Replace the text value of a set of nodes.
-- (Assumes a collection of <Building> nodes.)
UPDATE warehouses SET warehouse_spec = 
  updateXML(warehouse_spec,  
            '/Warehouse/Building/text()',
            'Owned');
-- Replace the text value of a set of nodes.
-- (Assumes a collection of <Building> nodes.)
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := . modify
            (for $i in $tmp/Warehouse/Building/text()  
             return replace value of node $i
                    with ''Owned'') 
            return $tmp'
           PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Insert a child under each node in a collection.
-- (Assumes a collection of <Building> nodes.)
UPDATE warehouses SET warehouse_spec = 
  insertChildXML(
    warehouse_spec, 
    '/Warehouse/Building',
    'Owner', 
    XMLType('<Owner>LesserCo</Owner>'));
-- Insert a child under each node in a collection.
-- (Assumes a collection of <Building> nodes.)
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := . modify
            (for $i in $tmp/Warehouse/Building
             return insert node       
             <Owner>LesserCo</Owner>
             into $i)
            return $tmp'
           PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Insert as child before the other children.
-- (Assumes a collection of <Owner> nodes.)
UPDATE warehouses SET warehouse_spec = 
  insertChildXMLbefore(
    warehouse_spec, 
    '/Warehouse/Building[1]',
    'Owner', 
    XMLType('<Owner>LesserCo</Owner>'));
-- Insert as child before the other children.
-- (Assumes a collection of <Owner> nodes.)
UPDATE warehouses SET warehouse_spec =
  XMLQuery(
    'copy $tmp := . modify
     (for $i in $tmp/Warehouse/Building[1]/Owner
      return insert node <Owner>LesserCo</Owner>
             before $i)
     return $tmp'
    PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Insert as child after the other children.
-- (Assumes a collection of <Owner> nodes.)
UPDATE warehouses SET warehouse_spec =
  insertChildXMLafter(
    warehouse_spec, 
    '/Warehouse/Building[1]',
    'Owner', 
    XMLType('<Owner>LesserCo</Owner>'));
-- Insert as child after the other children.
-- (Assumes a collection of <Owner> nodes.)
UPDATE warehouses SET warehouse_spec =
  XMLQuery(
    'copy $tmp := . modify
     (for $i in $tmp/Warehouse/Building[1]/Owner
      return insert node <Owner>LesserCo</Owner>
             after $i)
     return $tmp'
    PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Delete a node.
UPDATE warehouses SET warehouse_spec = 
  updateXML(warehouse_spec,
            '/Warehouse/Docks',
            NULL);
-- Delete a node.
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := . modify delete node 
            $tmp/Warehouse/Docks return $tmp'
           PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Replace with an empty node.
UPDATE warehouses SET warehouse_spec = 
  updateXML(warehouse_spec, '/Warehouse/Docks', '' );
-- Replace with an empty node.
UPDATE warehouses SET warehouse_spec =
  XMLQuery('copy $tmp := $p1 modify
            (for $j in $tmp/Warehouse/Docks
             return replace node $j with $p2)
            return $tmp'
           PASSING warehouse_spec "p1", '' AS "p2" 
           RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;
-- Update multiple paths.
UPDATE warehouses SET warehouse_spec = 
  updateXML(warehouse_spec,  
            '/Warehouse/Docks/text()', '4',
            '/Warehouse/Area/text()', '3500');
-- Update multiple paths.
UPDATE warehouses SET warehouse_spec =
  XMLQuery(
    'copy $tmp := . modify
     ((for $i in $tmp/Warehouse/Docks/text()  
       return replace value of node $i with 4),
      (for $i in $tmp/Warehouse/Area/text()  
       return replace value of node $i with 3500))
     return $tmp'
    PASSING warehouse_spec RETURNING CONTENT)
  WHERE warehouse_spec IS NOT NULL;

C.2 XMLデータを更新するための非推奨のOracle SQL関数

非推奨になる前は、次のOracle SQL関数を使用して、XMLデータを付加的に更新(周囲のXML文書全体を置き換えずにXMLデータを置換、挿入または削除)していました。これは、部分更新とも呼ばれます。

関数insertChildXMLinsertChildXMLbeforeinsertChildXMLafterinsertXMLbeforeinsertXMLafterおよびappendChildXMLは、XMLデータの挿入に使用します。関数deleteXMLは、XMLデータを削除します。関数updateXMLは、XMLデータを置換します。

特に、親ノード全体を置き換えることによってXMLデータを挿入または削除する場合は、関数updateXMLを使用しないでください。使用しても機能しますが、これ以外のいずれかの関数を使用するほうがローカルな更新を実行できるため、効率的です。

これらのOracle SQL関数はそれ自体ではデータベース・データを変更しません。これらはすべて副次的な影響のない純粋な関数です。各関数は、入力されたXMLデータにXPath式の引数を適用し、入力されたXMLデータの変更済コピーを戻します。その後、その結果を使用してSQL DML演算子UPDATEを実行し、データベース・データを変更できます。これは、SQL関数upperを使用してデータベース・データを大文字に変換する方法と変わりません。UPDATEなどのSQL DML演算子を使用して、格納されたデータを変更する必要があります。

これらの関数はそれぞれ、XML Schemaに基づくXML文書および基づかないXML文書のどちらにも使用できます。XML Schemaに基づくデータの場合、これらのOracle SQL関数はその結果に対して部分検証を実行します。該当する場合は、引数の値のXML Schemaとの互換性もチェックされます。

注意:

Oracle SQL関数およびXMLTypeメソッドは、W3C XPath勧告に準拠しています。このことは、XPath式がどのノードもターゲットにしていない場合にXMLデータに適用されると、空のシーケンスが戻される必要があることを示します。この場合にエラーが発生してはいけません

XPath式をXMLデータに適用するOracle SQL関数またはXMLTypeメソッドによって、何が戻されるのかが決まります。たとえば、XPath式の引数がどのノードもターゲットにしていない場合、SQL/XML関数XMLQueryNULLを戻し、deleteXMLなどの更新のOracle SQL関数(非推奨)は、入力されたXMLデータを変更せずに戻します。どのノードもターゲットになっていない場合にはエラーが発生することはありませんが、XPath式の引数が、属性ノードやテキスト・ノードなどの適切ではないノードをターゲットにしている場合は、更新のOracle SQL関数(非推奨)でエラーが発生する可能性があります。

関連項目:

XML Schemaに対する部分検証の詳細は、「XML Schemaの部分検証と全体検証」を参照してください

C.2.1 非推奨のOracle SQL関数を使用したXML要素の挿入

XMLノードを既存のXMLデータ(のコピー)に挿入するための非推奨のOracle SQL関数がいくつかあります。いずれも、XPath式により参照されるノードを複数の場所に挿入できます。各関数は、新しいノードの挿入位置と、ターゲットXMLデータの参照方法が異なります。

  • 関数appendChildXMLは、ターゲット要素にノードを追加します。つまり、ターゲット要素ごとに、任意の種類の1つ以上のノードを要素の最後の子として挿入します。

  • 関数insertChildXMLは、ターゲット要素の下に新しい子(同じ型の1つ以上の要素、または単一の属性)を挿入します。親の下の新しい子要素の位置は指定されません。ターゲット・データがXML Schemaに基づいている場合、そのスキーマを使用して挿入位置を指定できる場合もあります。できない場合、挿入位置は任意です。

  • 関数insertXMLbeforeは、任意の種類の1つ以上のノードを、ターゲット・ノード(属性ノード以外)の直前に挿入します。

    関数insertXMLafterも同様にノードを挿入しますが、ターゲットの直前ではなく直後に挿入します。

  • 関数insertChildXMLbeforeinsertChildXMLと似ていますが、挿入されるノードが(属性でなく)要素である必要があることと、兄弟関係における新しい要素の位置をユーザーが指定する点が異なります。これはinsertXMLbeforeと似ていますが、任意の要素ではなく、コレクション要素のみ挿入する点が異なります。挿入位置により、後続のコレクション・メンバーが指定されます。挿入する実際の要素は、コレクションの要素型に対応している必要があります。

    関数insertChildXMLafterも同様にノードを挿入しますが、ターゲットの直前ではなく直後に挿入します。

insertChildXMLbefore(insertChildXMLafter)とinsertXMLbefore(insertXMLbeforeafter)は結果は似ていますが、ターゲットの場所の表現方法が異なります。前者の関数では、ターゲットは新しい子の親です。後者の関数では、ターゲットは後ろの(または前の)兄弟です。この違いは、関数名(Child)に表れています。

たとえば、新しいLineItem要素を、要素/PurchaseOrder/LineItemsの3つ下にあるLineItem要素の前に挿入する場合、insertChildXMLbeforeを使用し、ターゲットの親を/PurchaseOrder/LineItemsとして指定し、後続の兄弟をLineItem[3]として指定します。または、insertXMLbeforeを使用し、ターゲットの後続の兄弟を/PurchaseOrder/LineItems/LineItem[3]として指定することもできます。insertChildXMLを使用して挿入する場合は、コレクション内の新しい要素の位置を指定できません。どの位置になるかは不確定です。

さらにこれらの関数は、insertXMLbeforeinsertXMLafterおよびappendChildXML除くすべてが、オブジェクト・リレーショナル形式またはバイナリXMLとして格納されている、XMLType表および列に対するSQL UPDATE操作のために最適化されている点が異なります。

C.3 UPDATEXML (非推奨のOracle SQL関数)

非推奨のOracle SQL関数updateXMLは、任意の種類のXMLノードを置換します。更新のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数updateXMLには、次のパラメータがあります(この順序どおり)。

  • target-data (XMLType) - 置換するターゲット・ノードを含むXMLデータ。

  • xpathパラメータとreplacementパラメータの1つ以上の

    • xpath (VARCHAR2) - target-data内で置換するノードを検索するXPath 1.0式。それぞれのターゲットとなるノードは、replacementにより置換されます。これらは、どのような種類のノードでもかまいません。xpathがノードの空のシーケンスと一致する場合、置換は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。

    • replacement (XMLTypeまたはVARCHAR2) - xpathでターゲットとなっているデータを置換するXMLデータ。replacementのデータ型は、置換されるデータと一致している必要があります。xpathが要素ノードを置換の対象とする場合、データ型はXMLTypeである必要があります。xpathが属性ノードやテキスト・ノードをターゲットにする場合は、VARCHAR2である必要があります。属性ノードの場合、replacementは、名前を含む完全な属性ノード(たとえばmy_attribute="23")ではなく、属性の置換のみ(たとえば23)です。

  • namespace (VARCHAR2オプション) - パラメータxpathのXML名前空間。

非推奨のOracle SQL関数updateXMLを使用すると、既存の要素、属性およびノードを新しい値で置換できます。新しいノードを挿入したり、既存のノードを削除することは、効率的な方法ではありませんupdateXMLを使用して、挿入または削除するノードの親ノード全体を置換するだけで、挿入および削除を実行できます。

関数updateXMLは、メモリー内の一時XMLインスタンスのみを更新します。表に格納されたデータを更新するには、SQLのUPDATE文を使用します。

図C-1に構文を示します。

例C-1では、新しいXML文書を作成するのではなく、UPDATE文の右側にupdateXMLを使用して表内のXML文書を更新します。選択された部分のみではなく、文書全体が更新されます。

例C-2では、Oracle SQL関数updateXMLを使用して複数のノードを更新します。

例C-3では、SQL関数updateXMLを使用して、コレクション内で選択されたノードを更新します。

例C-1 UPDATEおよびUPDATEXMLを使用したXMLTYPEの更新(非推奨)

SELECT XMLQuery('$p/PurchaseOrder/Actions/Action[1]' PASSING po.OBJECT_VALUE AS "p"
                                                     RETURNING CONTENT) action
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
ACTION
--------------------------------
<Action>
  <User>SVOLLMAN</User>
</Action>

UPDATE purchaseorder po
  SET po.OBJECT_VALUE = updateXML(po.OBJECT_VALUE, 
                                  '/PurchaseOrder/Actions/Action[1]/User/text()',
                                  'SKING')
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
SELECT XMLQuery('$p/PurchaseOrder/Actions/Action[1]' PASSING po.OBJECT_VALUE AS "p"
                                                     RETURNING CONTENT) action
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
ACTION
---------------------------------
<Action>
  <User>SKING</User>
</Action>

例C-2 UPDATEXMLを使用した、複数のテキスト・ノードと属性値の更新(非推奨)

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(30)) name,
       XMLQuery('$p/PurchaseOrder/LineItems'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
NAME             LINEITEMS
---------------- ------------------------------------------------------------------------
Sarah J. Bell    <LineItems>
                   <LineItem ItemNumber="1">
                     <Description>A Night to Remember</Description>
                     <Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
                   </LineItem>
                   <LineItem ItemNumber="2">
                     <Description>The Unbearable Lightness Of Being</Description>
                     <Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
                   </LineItem>
                   <LineItem ItemNumber="3">
                     <Description>Sisters</Description>
                     <Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
                   </LineItem>
                 </LineItems>

UPDATE purchaseorder
  SET OBJECT_VALUE = updateXML(OBJECT_VALUE,
                               '/PurchaseOrder/Requestor/text()','Stephen G. King',
                               '/PurchaseOrder/LineItems/LineItem[1]/Part/@Id','786936150421',
                               '/PurchaseOrder/LineItems/LineItem[1]/Description/text()','The Rock',
                               '/PurchaseOrder/LineItems/LineItem[3]',
                               XMLType('<LineItem ItemNumber="99">
                                          <Description>Dead Ringers</Description>
                                          <Part Id="715515009249" UnitPrice="39.95" Quantity="2"/>
                                        </LineItem>'))
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(30)) name,
       XMLQuery('$p/PurchaseOrder/LineItems'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
NAME             LINEITEMS
---------------- ------------------------------------------------------------------
Stephen G. King  <LineItems>
                   <LineItem ItemNumber="1">
                     <Description>The Rock</Description>
                     <Part Id="786936150421" UnitPrice="39.95" Quantity="2"/>
                   </LineItem>
                   <LineItem ItemNumber="2">
                     <Description>The Unbearable Lightness Of Being</Description>
                     <Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
                   </LineItem>
                   <LineItem ItemNumber="99">
                     <Description>Dead Ringers</Description>
                     <Part Id="715515009249" UnitPrice="39.95" Quantity="2"/>
                   </LineItem>
                 </LineItems>

例C-3 UPDATEXMLを使用した、コレクション内で選択されたノードの更新(非推奨)

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(30)) name,
       XMLQuery('$p/PurchaseOrder/LineItems'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
NAME             LINEITEMS
---------------- ----------------------------------------------------------------
Sarah J. Bell    <LineItems>
                   <LineItem ItemNumber="1">
                     <Description>A Night to Remember</Description>
                     <Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
                   </LineItem>
                   <LineItem ItemNumber="2">
                     <Description>The Unbearable Lightness Of Being</Description>
                     <Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
                   </LineItem>
                   <LineItem ItemNumber="3">
                     <Description>Sisters</Description>
                     <Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
                   </LineItem>
                 </LineItems>

UPDATE purchaseorder
  SET OBJECT_VALUE = 
      updateXML(OBJECT_VALUE,
                '/PurchaseOrder/Requestor/text()','Stephen G. King',
                '/PurchaseOrder/LineItems/LineItem/Part[@Id="715515009058"]/@Quantity',
                25,
                '/PurchaseOrder/LineItems/LineItem[Description/text() =
                                                   "The Unbearable Lightness Of Being"]',
                XMLType('<LineItem ItemNumber="99">
                           <Part Id="786936150421" Quantity="5" UnitPrice="29.95"/>
                           <Description>The Rock</Description>
                         </LineItem>'))
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(30)) name,
       XMLQuery('$p/PurchaseOrder/LineItems'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
NAME             LINEITEMS
---------------- -------------------------------------------------------------
Stephen G. King  <LineItems>
                   <LineItem ItemNumber="1">
                     <Description>A Night to Remember</Description>
                     <Part Id="715515009058" UnitPrice="39.95" Quantity="25"/>
                   </LineItem>
                   <LineItem ItemNumber="99">
                     <Part Id="786936150421" Quantity="5" UnitPrice="29.95"/>
                     <Description>The Rock</Description>
                   </LineItem>
                   <LineItem ItemNumber="3">
                     <Description>Sisters</Description>
                     <Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
                   </LineItem>
                 </LineItems>

C.3.1 非推奨のOracle SQL関数UPDATEXMLおよびNULL値

非推奨のOracle SQL関数updateXMLNULL値を指定して使用する場合は、いくつかの考慮事項が適用されます。

  • XML要素NULLに更新すると、要素の属性および子が削除され、要素は空になります。要素のタイプおよび名前空間プロパティは保持されます。例C-4を参照してください。

  • 属性値をNULLに更新した場合、値は空の文字列として表示されます。例C-4を参照してください。

  • 要素のテキスト・ノードをNULLに更新すると、その要素のコンテンツ(テキスト)は削除されます。要素自体は残りますが、空になります。例C-5を参照してください。

例C-4では、次のものすべてをNULLに更新します。

  • Description要素と、Part要素の属性Id値が715515009058のLineItem要素のQuantity属性

  • Description要素のコンテンツ(テキスト)が「The Unbearable Lightness Of Being」であるLineItem要素

例C-5では、Description属性の値が"A Night to Remember"であるPart要素のテキスト・ノードをNULLに更新します。この例のXMLデータは、修正された別の発注書XML Schemaに対応しています(「コピーに基づく拡張の使用例」を参照)。そのXML Schemaでは、DescriptionPart要素の属性であり、兄弟要素ではありません。

関連項目:

例3-26

例C-4 UPDATEXMLを使用したNULL更新(非推奨): 要素および属性

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(30)) name,
       XMLQuery('$p/PurchaseOrder/LineItems'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
NAME             LINEITEMS
---------------- -------------------------------------------------------------------
Sarah J. Bell    <LineItems>
                   <LineItem ItemNumber="1">
                     <Description>A Night to Remember</Description>
                     <Part Id="715515009058" UnitPrice="39.95" Quantity="2"/>
                   </LineItem>
                   <LineItem ItemNumber="2">
                     <Description>The Unbearable Lightness Of Being</Description>
                     <Part Id="37429140222" UnitPrice="29.95" Quantity="2"/>
                   </LineItem>
                   <LineItem ItemNumber="3">
                     <Description>Sisters</Description>
                     <Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
                   </LineItem>
                 </LineItems>

UPDATE purchaseorder
  SET OBJECT_VALUE = 
      updateXML(
        OBJECT_VALUE,
        '/PurchaseOrder/LineItems/LineItem[Part/@Id="715515009058"]/Description', NULL,
             '/PurchaseOrder/LineItems/LineItem/Part[@Id="715515009058"]/@Quantity', NULL,
        '/PurchaseOrder/LineItems/LineItem[Description/text()=
                                           "The Unbearable Lightness Of Being"]', NULL)
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/Requestor'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(30)) name,
       XMLQuery('$p/PurchaseOrder/LineItems'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT) lineitems
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 
NAME             LINEITEMS
---------------- ----------------------------------------------------------------
Sarah J. Bell    <LineItems>
                   <LineItem ItemNumber="1">
                     <Description/>
                     <Part Id="715515009058" UnitPrice="39.95" Quantity=""/>
                   </LineItem>
                   <LineItem/>
                   <LineItem ItemNumber="3">
                     <Description>Sisters</Description>
                     <Part Id="715515011020" UnitPrice="29.95" Quantity="4"/>
                   </LineItem>
                 </LineItems>

例C-5 UPDATEXMLを使用したNULL更新(非推奨): テキスト・ノード

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/LineItems/LineItem/Part[@Description="A Night to Remember"]'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(128)) part
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[@Reference="SBELL-2003030912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

PART
----
<Part Description="A Night to Remember" UnitCost="39.95">715515009058</Part>

UPDATE purchaseorder
  SET OBJECT_VALUE = 
        updateXML(OBJECT_VALUE, 
                  '/PurchaseOrder/LineItems/LineItem/Part[@Description="A Night to Remember"]/text()', NULL)
  WHERE XMLExists('$p/PurchaseOrder[@Reference="SBELL-2003030912333601PDT"]'
                  PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/LineItems/LineItem/Part[@Description="A Night to Remember"]'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(128)) part
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[@Reference="SBELL-2003030912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

PART
----
<Part Description="A Night to Remember" UnitCost="39.95"/>

C.3.2 UPDATEXMLを使用した同じXMLノードの複数回の更新(非推奨)

同じXMLノードをupdateXML式で複数回更新できます。更新の順番は、左から右へ、XPath式の順番によって決定されます。連続する更新はそれぞれ、前の更新結果に基づいて機能します。

たとえば、/EMP[EMPNO=217]および/EMP[EMPNAME="Jane"]/EMPNOの両方を更新できます。ここで最初のXPathはそれを含むEMPNOノードも識別します。

C.3.3 UPDATEXML使用時のDOM再現性のガイドライン(非推奨)

Oracle SQL関数updateXMLを使用するときのDOM再現性に関するガイドラインを示します。

  • DOM再現性が維持される場合 -

    要素をNULLに更新すると、その要素がその親でに表示されるようになります。要素内のテキスト・ノードをNULLに更新すると、そのテキスト・ノードが削除されます。属性ノードをNULLに更新すると、属性値がの文字列になります。

    空の要素の例は、<myElem/>です。文字列値が空の属性の例は、myAttr=""です。

  • DOM再現性が維持されない場合 -

    complexType要素をNULLに更新すると、これがその親でに表示されるようになります。SQLインラインsimpleType要素をNULLに更新すると、これがその親で表示されなくなります。テキスト・ノードをNULLに更新することは、親simpleType要素をNULLに設定することと同じです。

    また、複合コンテンツを格納する位置指定ディスクリプタがないため、DOM再現性が維持されない場合、テキスト・ノードはsimpleType要素内にのみ出現できます。属性ノードをNULLに更新すると、要素からその属性が削除されます。

  • DOM再現性が維持されるかどうかの判別方法 -

    特定のXML Schema内の特定のXMLTypeインスタンスの特定部分についてDOM再現性が維持されるかどうかを判別するには、属性maintainDOMのXML Schemaメタデータを問い合せます。

    関連項目:

C.4 XMLデータを変更する非推奨のOracle SQL関数の最適化

ほとんどの場合、XMLデータを変更する非推奨のOracle SQL関数は、入力されたXML文書全体のコピーをメモリー内に生成してから、そのコピーを更新します。ただし、関数updateXMLinsertChildXMLinsertChildXMLbeforeinsertChildXMLafterおよびdeleteXML、つまり、insertXMLbeforeinsertXMLafterおよびappendChildXML除くすべてがXMLType UPDATE操作のために最適化されます。

オブジェクト・リレーショナル記憶域の場合、特定の条件が満たされると、関数コールは、オブジェクト・リレーショナル列を新しい値で直接更新するようにリライトできます。バイナリXML記憶域の場合、ターゲットの更新の前のデータは変更されず、SecureFiles LOBが使用されている場合(デフォルトの動作)は、スライド挿入を使用して、変更が必要なデータ部分のみが更新されます。

オブジェクト・リレーショナル記憶域の例では、例C-6に記載されているupdateXMLへのXPath引数は、Oracle XML DBで処理され、例C-7に記載されている同等のオブジェクト・リレーショナルSQLコードにリライトされます。

注意:

ここで説明するDML用のXMLDATAの使用方法は、Oracle XML DBの内部動作の説明に限定されます。DML操作には、XMLDATA自身を使用しないでください。XMLDATAを直接使用できるのは、DDL操作に対してのみで、DML操作には使用できません。

一般的に、コード内ではXML Schemaオブジェクト・モデルとSQLオブジェクト・モデル間の現在のマッピングに依存しないでください。Oracle XML DB実装のマッピングは将来変更される可能性があります。

例C-6 UPDATEXML式内のXPath式

SET LONG 2000
--
SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
       AS VARCHAR2(30))
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
  PASSING po.OBJECT_VALUE AS "p");
 
XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SBELL

UPDATE purchaseorder
  SET OBJECT_VALUE = updateXML(OBJECT_VALUE, '/PurchaseOrder/User/text()', 'SVOLLMAN')
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
  PASSING OBJECT_VALUE AS "p");

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User'
PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
       AS VARCHAR2(30))
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
  PASSING po.OBJECT_VALUE AS "p");
 
XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SVOLLMAN

例C-7 UPDATEXML式と同等のオブジェクト・リレーショナル形式の文

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(30))
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SBELL
 
UPDATE purchaseorder p
   SET p."XMLDATA"."USERID" = 'SVOLLMAN'
   WHERE p."XMLDATA"."REFERENCE" = 'SBELL-2002100912333601PDT';

SELECT XMLCast(XMLQuery('$p/PurchaseOrder/User'
                        PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
               AS VARCHAR2(30))
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");
 

XMLCAST(XMLQUERY('$P/PURCHASEO
------------------------------
SVOLLMAN

C.5 XMLデータを変更する非推奨のOracle SQL関数を使用した、XMLビューの作成

XMLデータを変更する非推奨のOracle SQL関数(updateXMLinsertChildXMLinsertChildXMLbeforeinsertChildXMLafterinsertXMLbeforeinsertXMLafterappendChildXMLおよびdeleteXML)を使用して、XMLデータの新しいビューを作成できます。

例C-8では、非推奨のOracle SQL関数updateXMLを使用してpurchaseorder表のビューを作成します。

例C-8 UPDATEXMLを使用したビューの作成(非推奨)

CREATE OR REPLACE VIEW purchaseorder_summary OF XMLType AS
  SELECT updateXML(OBJECT_VALUE,
                   '/PurchaseOrder/Actions', NULL,
                   '/PurchaseOrder/ShippingInstructions', NULL,
                   '/PurchaseOrder/LineItems', NULL) AS XML
  FROM purchaseorder p;

SELECT OBJECT_VALUE FROM purchaseorder_summary
  WHERE XMLExists('$p/PurchaseOrder[Reference="DAUSTIN-20021009123335811PDT"]'
                  PASSING OBJECT_VALUE AS "p");
 
OBJECT_VALUE
---------------------------------------------------------------------------
<PurchaseOrder
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation=
      "http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd">
  <Reference>DAUSTIN-20021009123335811PDT</Reference>
  <Actions/>
  <Reject/>
  <Requestor>David L. Austin</Requestor>
  <User>DAUSTIN</User>
  <CostCenter>S30</CostCenter>
  <ShippingInstructions/>
  <SpecialInstructions>Courier</SpecialInstructions>
  <LineItems/>
</PurchaseOrder>

C.6 INSERTCHILDXML (非推奨のOracle SQL関数)

非推奨のOracle SQL関数insertChildXMLは、親のXML要素の下に新しい子(同じ型の1つ以上の要素、または単一の属性)を挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertChildXMLには、次のパラメータがあります(この順序どおり)。

  • target-data (XMLType) - ターゲットの親要素を含むXMLデータ。

  • parent-xpath (VARCHAR2) - target-data内で親要素を検索するXPath 1.0式。child-dataは、それぞれの親要素の下に挿入されます。

    parent-xpathが要素ノードの空のシーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。parent-xpathが要素ノードのシーケンスと一致しない場合(特に、parent-xpathが1つ以上の属性ノードまたはテキスト・ノードと一致する場合)、エラーが発生します。

  • child-name (VARCHAR2) - 挿入する子要素または属性の名前。属性名は、child-nameの一部として先頭にアットマーク(@)が付くことで、要素名と区別されます。たとえば、@my_attributemy_elementです。(アットマークは属性名の一部ではありませんが、引数内でchild-nameが属性であることを示す働きをします。)

  • child-data (XMLTypeまたはVARCHAR2) - 挿入する子XMLデータ。

    • 1つ以上の要素を挿入する場合、このデータ型はXMLTypeで、要素ノードを含みます。child-data内の最上位の要素ノードはそれぞれchild-nameと同じ名前(タグ)を持つ必要があります(そうでない場合、エラーが発生します)。

    • 属性を挿入する場合、このデータ型はVARCHAR2で、(スカラー)属性値を表します。挿入位置に同じ名前の属性がすでに存在する場合、エラーが発生します。

  • namespace (VARCHAR2オプション) - パラメータparent-xpathおよびchild-dataのXML名前空間。

XMLデータchild-dataは、1つ以上の子要素として、または単一の子属性として、parent-xpathで見つかった親要素の下に挿入されます。

NULL引数に対する関数insertChildXMLの動作は、次のとおりです(優先順位の高い順に示します)。

  • child-nameNULLの場合、エラーが発生します。

  • target-dataまたはparent-xpathNULLの場合、NULLが戻されます。

  • child-dataNULLの場合、次のようになります。

    • child-name名が要素名の場合、挿入は行われず、target-dataがそのままの状態で戻されます。

    • child-name名が属性名の場合、空の属性値が挿入されます。たとえば、my_attribute = ""になります。

図C-2に構文を示します。

図C-2 INSERTCHILDXMLの構文

図C-2の説明が続きます。
「図C-2 INSERTCHILDXMLの構文」の説明

target-dataがXML Schemaに基づいている場合、そのスキーマを参照して挿入位置が決定されます。たとえば、スキーマがchild-nameという子要素をparent-xpathの最初の子要素に制限している場合、挿入はこれに基づいて行われます。同様に、child-nameまたはchild-data引数が、関連付けられたスキーマに対して不適切である場合は、エラーが発生します。

親要素がchild-nameという名前と種類に対応する子を持っていない場合(かつ、関連付けられたXML Schemaが存在し、そのスキーマによってそのような子が許可されている場合)、child-dataが、child-nameという名前で、新しい子要素または新しい属性値として挿入されます。

親要素がすでにchild-nameという名前(アットマークなし)の子属性を持つ場合は、エラーが発生します。親要素がすでにchild-nameという名前の子要素を持つ場合(かつ、関連付けられたXML Schemaが存在し、そのスキーマによって複数の子要素が許可されている場合)、child-dataは、その要素がchild-nameという名前の子要素になるように挿入されます。ただし、子シーケンス内での位置は予測できません。

既存の空でない子要素のコレクションに要素を挿入する必要があり、順序が重要な場合は、SQL/XML関数appendChildXMLまたはinsertXMLbeforeを使用してください。

例C-9に、SQL UPDATE文とOracle SQL関数insertChildXMLを使用して、新しいLineItem要素をLineItems要素の子として挿入する方法を示します。

更新するXMLデータがXMLスキーマに基づいていて、ネームスペースを参照する場合、挿入するデータも同じネームスペースを参照する必要があります。参照しない場合は、挿入されるデータがXMLスキーマに準拠しないため、エラーが発生します。

例C-10例C-9と似ていますが、挿入されるLineItem要素が名前空間を参照しています。これは、関連するXML Schemaでこの要素に対する名前空間が必要であることを前提としています。

このような名前空間の使用方法は、関数insertChildXMLに対する名前空間引数の使用方法とは異なるため、注意してください。そのオプションの引数に指定される名前空間は、挿入されるコンテンツではなく、XPath引数のみに適用されます。

例C-9 INSERTCHILDXMLを使用したコレクションへの挿入(非推奨)

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[@ItemNumber=222]'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[@ITEMNUMBER=222]'
---------------------------------------------------------------

1 row selected.

UPDATE purchaseorder
  SET OBJECT_VALUE = 
        insertChildXML(OBJECT_VALUE, 
                       '/PurchaseOrder/LineItems', 
                       'LineItem', 
                       XMLType('<LineItem ItemNumber="222">
                                  <Description>The Harder They Come</Description>
                                  <Part Id="953562951413" 
                                        UnitPrice="22.95" 
                                        Quantity="1"/>
                                </LineItem>'))
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[@ItemNumber=222]'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[@ITEMNUMBER=222]'
---------------------------------------------------------------
<LineItem ItemNumber="222">
  <Description>The Harder They Come</Description>
  <Part Id="953562951413" UnitPrice="22.95" Quantity="1"/>
</LineItem>

1 row selected.

例C-10 名前空間を使用する要素の挿入

UPDATE purchaseorder
  SET OBJECT_VALUE = 
        insertChildXML(OBJECT_VALUE, 
                       '/PurchaseOrder/LineItems', 
                       'LineItem', 
                       XMLType('<LineItem xmlns="films.xsd" ItemNumber="222">
                                  <Description>The Harder They Come</Description>
                                  <Part Id="953562951413" 
                                        UnitPrice="22.95" 
                                        Quantity="1"/>
                                </LineItem>'))
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING OBJECT_VALUE AS "p");

C.7 INSERTCHILDXMLBEFORE (非推奨のOracle SQL関数)

非推奨のOracle SQL関数insertChildXMLbeforeは、1つ以上のコレクション要素をターゲットの親要素の子として挿入します。各ターゲットは、指定された既存のコレクション要素の直前に挿入されます。挿入のターゲットである既存のXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertChildXMLbeforeには、次のパラメータがあります(この順序どおり)。

  • target-data (XMLType) - 挿入のターゲットであるXMLデータ。

  • parent-xpath (VARCHAR2) - target-data内で親要素を検索するXPath 1.0式。child-dataは、それぞれの親要素の下に挿入されます。

    parent-xpathが要素ノードの空のシーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。parent-xpathが要素ノードのシーケンスと一致しない場合(特に、parent-xpathが1つ以上の属性ノードまたはテキスト・ノードと一致する場合)、エラーが発生します。

  • child-xpath (VARCHAR2) - 挿入されるchild-dataの直後の位置の既存の子を検索する相対XPath 1.0式。これは、parent-xpathに示された要素の子要素に名前を指定している必要があります。また、述語を含めることもできます。

  • child-data (XMLType) - 挿入する子要素XMLデータ。このデータ型は常にXMLTypeであり、要素ノードを含んでいます。child-data内の最上位の要素ノードはそれぞれchild-xpathに示された要素と同じデータ型を持つ必要があります(そうでない場合、エラーが発生します)。

  • namespace (オプションVARCHAR2) - パラメータparent-xpathchild-xpathおよびchild-dataの名前空間。

XMLデータchild-dataは、1つ以上の子要素として、parent-xpathで見つかった親要素の下に挿入されます。

NULL引数に対する関数insertChildXMLbeforeの動作は、次のとおりです(優先順位の高い順に示します)。

  • child-xpathNULLの場合、エラーが発生します。

  • target-dataまたはparent-xpathNULLの場合、NULLが戻されます。

  • child-dataNULLの場合、挿入は行われず、target-dataがそのままの状態で戻されます。

図C-3に構文を示します。

図C-3 INSERTCHILDXMLBEFOREの構文

図C-3の説明が続きます。
「図C-3 INSERTCHILDXMLBEFOREの構文」の説明

C.8 INSERTCHILDXMLAFTER (非推奨のOracle SQL関数)

非推奨のOracle SQL関数insertChildXMLafterは、1つ以上のコレクション要素をターゲットの親要素の子として挿入します。各ターゲットは、指定された既存のコレクション要素の直後に挿入されます。挿入のターゲットである既存のXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertChildXMLafterには、次のパラメータがあります(この順序どおり)。

  • target-data (XMLType) - 挿入のターゲットであるXMLデータ。

  • parent-xpath (VARCHAR2) - target-data内で親要素を検索するXPath 1.0式。child-dataは、それぞれの親要素の下に挿入されます。

    parent-xpathが要素ノードの空のシーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。parent-xpathが要素ノードのシーケンスと一致しない場合(特に、parent-xpathが1つ以上の属性ノードまたはテキスト・ノードと一致する場合)、エラーが発生します。

  • child-xpath (VARCHAR2) - 挿入されるchild-dataの直前の位置の既存の子を検索する相対XPath 1.0式。これは、parent-xpathに示された要素の子要素に名前を指定している必要があります。また、述語を含めることもできます。

  • child-data (XMLType) - 挿入する子要素XMLデータ。このデータ型は常にXMLTypeであり、要素ノードを含んでいます。child-data内の最上位の要素ノードはそれぞれchild-xpathに示された要素と同じデータ型を持つ必要があります(そうでない場合、エラーが発生します)。

  • namespace (オプションVARCHAR2) - パラメータparent-xpathchild-xpathおよびchild-dataの名前空間。

XMLデータchild-dataは、1つ以上の子要素として、parent-xpathで見つかった親要素の下に挿入されます。

NULL引数に対する関数insertChildXMLafterの動作は、次のとおりです(優先順位の高い順に示します)。

  • child-xpathNULLの場合、エラーが発生します。

  • target-dataまたはparent-xpathNULLの場合、NULLが戻されます。

  • child-dataNULLの場合、挿入は行われず、target-dataがそのままの状態で戻されます。

図C-4に構文を示します。

図C-4 INSERTCHILDXMLAFTERの構文

図C-4の説明が続きます。
「図C-4 INSERTCHILDXMLAFTERの構文」の説明

C.9 INSERTXMLBEFORE (非推奨のOracle SQL関数)

非推奨のOracle SQL関数insertXMLbeforeは、任意の種類の1つ以上のノードを、属性ノード以外のターゲット・ノードの直前に挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertXMLbeforeには、次のパラメータがあります(この順序どおり)。

  • target-data (XMLType) - 挿入のターゲットであるXMLデータ。

  • successor-xpath (VARCHAR2) - 属性ノード以外の種類のtarget-data内で0個以上のノードを検索するXPath 1.0式。XML-dataが、これらのノードの直前に挿入されます。こうすれば、XML-dataのノードは、successor-xpathノードの前にある各兄弟になります。

    successor-xpathがノードの空のシーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。successor-xpathが、属性ノード以外のノードのシーケンスと一致しない場合、エラーが発生します。

  • XML-data (XMLType) - 挿入されるXMLデータ。任意の種類の1つ以上のノード。ノードの順序は、挿入後も保持されます。

  • namespace (オプションVARCHAR2) - パラメータsuccessor-xpathの名前空間。

XML-dataノードは、successor-xpathで見つかった属性以外のノードそれぞれの直前に挿入されます。

関数insertXMLbeforeNULL引数に対する動作は、次のとおりです。

  • target-dataまたはparent-xpathNULLの場合、NULLが戻されます。

  • それ以外の場合、child-dataNULLであれば、挿入は行われず、target-dataがそのままの状態で戻されます。

図C-5に構文を示します。

図C-5 INSERTXMLBEFOREの構文

図C-5の説明が続きます。
「図C-5 INSERTXMLBEFOREの構文」の説明

例C-11では、非推奨のOracle SQL関数insertXMLbeforeを使用して、LineItem要素を最初のLineItem要素の前に挿入します。

注意:

Oracle SQL関数insertXMLbeforeを使用する問合せは、最適化されません。このため、関数insertChildXMLinsertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。XQuery用のパフォーマンス・チューニングを参照してください。

例C-11 INSERTXMLBEFOREを使用した要素の前への挿入(非推奨)

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[1]'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                   PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[1]'PASSINGPO.OBJECT_
------------------------------------------------------------------
<LineItem ItemNumber="1">
  <Description>Salesman</Description>
  <Part Id="37429158920" UnitPrice="39.95" Quantity="2"/>
</LineItem>

UPDATE purchaseorder
  SET OBJECT_VALUE = 
      insertXMLbefore(OBJECT_VALUE, 
                      '/PurchaseOrder/LineItems/LineItem[1]', 
                      XMLType('<LineItem ItemNumber="314">
                                 <Description>Brazil</Description>
                                 <Part Id="314159265359" 
                                       UnitPrice="69.95" 
                                       Quantity="2"/>
                               </LineItem>'))
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[position() <= 2]'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                   PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[POSITION()<=2]'PASSINGPO.OBJECT_
------------------------------------------------------------------------------
<LineItem ItemNumber="314">
  <Description>Brazil</Description>
  <Part Id="314159265359" UnitPrice="69.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="1">
  <Description>Salesman</Description>
  <Part Id="37429158920" UnitPrice="39.95" Quantity="2"/>
</LineItem>

C.10 INSERTXMLAFTER (非推奨のOracle SQL関数)

非推奨のOracle SQL関数insertXMLafterは、任意の種類の1つ以上のノードを、属性ノード以外のターゲット・ノードの直後に挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

そのため、関数insertXMLafterinsertXMLbeforeと似ていますが、ターゲット・ノードの前ではなく後に挿入します。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数insertXMLafterには、次のパラメータがあります(この順序どおり)。

  • target-data (XMLType) - 挿入のターゲットであるXMLデータ。

  • successor-xpath (VARCHAR2) - 属性ノード以外の種類のtarget-data内で0個以上のノードを検索するXPath 1.0式。XML-dataが、これらのノードの直後に挿入されます。こうすれば、XML-dataのノードは、successor-xpathノードの後ろにある各兄弟になります。

    successor-xpathがノードの空のシーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。successor-xpathが、属性ノード以外のノードのシーケンスと一致しない場合、エラーが発生します。

  • XML-data (XMLType) - 挿入されるXMLデータ。任意の種類の1つ以上のノード。ノードの順序は、挿入後も保持されます。

  • namespace (オプションVARCHAR2) - パラメータsuccessor-xpathの名前空間。

XML-dataノードは、successor-xpathで見つかった属性以外のノードそれぞれの直後に挿入されます。

関数insertXMLafterNULL引数に対する動作は、次のとおりです。

  • target-dataまたはparent-xpathNULLの場合、NULLが戻されます。

  • それ以外の場合、child-dataNULLであれば、挿入は行われず、target-dataがそのままの状態で戻されます。

図C-6に構文を示します。

図C-6 INSERTXMLAFTERの構文

図C-6の説明が続きます。
「図C-6 INSERTXMLAFTERの構文」の説明

注意:

Oracle SQL関数insertXMLafterを使用する問合せは、最適化されません。このため、関数insertChildXMLinsertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。XQuery用のパフォーマンス・チューニングを参照してください。

C.11 APPENDCHILDXML (非推奨のOracle SQL関数)

非推奨のOracle SQL関数appendChildXMLは、任意の種類の1つ以上のノードを、指定された要素ノードの最後の子として挿入します。挿入のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数appendChildXMLには、次のパラメータがあります(この順序どおり)。

  • target-data (XMLType) - ターゲットの親要素を含むXMLデータ。

  • parent-xpath (VARCHAR2) - 挿入操作のターゲットであるtarget-dataにあるゼロまたは複数の要素ノードを検索するXPath 1.0式。child-dataは、こうした親要素の最後の子として挿入されます。

    parent-xpathが要素ノードの空のシーケンスと一致する場合、挿入は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。parent-xpathが要素ノードのシーケンスと一致しない場合(特に、parent-xpathが1つ以上の属性ノードまたはテキスト・ノードと一致する場合)、エラーが発生します。

  • child-data (XMLType) - 挿入される子データ。任意の種類の1つ以上のノード。ノードの順序は、挿入後も保持されます。

  • namespace (オプションVARCHAR2) - パラメータparent-xpathの名前空間。

XMLデータchild-dataは、parent-xpathにより指定された要素ノードの最後の子として挿入されます。

関数appendChildXMLNULL引数に対する動作は、次のとおりです。

  • target-dataまたはparent-xpathNULLの場合、NULLが戻されます。

  • それ以外の場合、child-dataNULLであれば、挿入は行われず、target-dataがそのままの状態で戻されます。

図C-7に構文を示します。

図C-7 APPENDCHILDXMLの構文

図C-7の説明が続きます。
「図C-7 APPENDCHILDXMLの構文」の説明

例C-12では、非推奨のOracle SQL関数appendChildXMLを使用して、Date要素をAction要素の最後の子として挿入します。

注意:

Oracle SQL関数appendChildXMLを使用する問合せは、最適化されません。このため、関数insertChildXMLinsertChildXMLbeforeまたはinsertChildXMLafterをかわりに使用することをお薦めします。XQuery用のパフォーマンス・チューニングを参照してください。

例C-12 APPENDCHILDXMLを使用した最後の子としての挿入(非推奨)

SELECT XMLQuery('$p/PurchaseOrder/Actions/Action[1]'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/ACTIONS/ACTION[1]'PASSINGPO.OBJECT_VALUE
-------------------------------------------------------------------
<Action>
  <User>KPARTNER</User>
</Action>

UPDATE purchaseorder
  SET OBJECT_VALUE = 
      appendChildXML(OBJECT_VALUE, 
                     'PurchaseOrder/Actions/Action[1]', 
                     XMLType('<Date>2002-11-04</Date>'))
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/Actions/Action[1]'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/ACTIONS/ACTION[1]'PASSINGPO.OBJECT_VALUE
-------------------------------------------------------------------
<Action>
  <User>KPARTNER</User>
  <Date>2002-11-04</Date>
</Action>

C.12 DELETEXML (非推奨のOracle SQL関数)

非推奨のOracle SQL関数deleteXMLは、任意の種類のXMLノードを削除します。削除のターゲットであるXML文書は、XML Schemaに基づく文書でも、XML Schemaに基づかない文書でもかまいません。

入力XMLTypeインスタンスのコピーが変更されて戻されます。元のデータは影響を受けません。その戻されたデータを使用してSQL操作UPDATEを実行し、データベース・データを更新できます。

関数deleteXMLには、次のパラメータがあります(この順序どおり)。

  • target-data (XMLType) - (削除される)ターゲット・ノードを含むXMLデータ。

  • xpath (VARCHAR2) - 削除操作のターゲットであるtarget-dataにあるゼロまたは複数のノードを検索するXPath 1.0式。こうしたノードは削除されます。

    xpathがノードの空のシーケンスと一致する場合、削除は行われず、target-dataがそのままの状態で戻されます(エラーは発生しません)。xpathが最上位の要素ノードと一致する場合、エラーが発生します。

  • namespace (オプションVARCHAR2) - パラメータxpathの名前空間。

xpathで見つかったXMLノードがtarget-dataから削除されます。target-dataまたはxpathNULLの場合、関数deleteXMLNULLを戻します。

図C-8に構文を示します。

例C-13では、非推奨のOracle SQL関数deleteXMLを使用して、ItemNumber属性の値が222LineItem要素を削除します。

例C-13 DELETEXMLを使用した要素の削除(非推奨)

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[@ItemNumber=222]'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[@ITEMNUMBER=222]'PASSINGPO
------------------------------------------------------------------------
<LineItem ItemNumber="222">
  <Description>The Harder They Come</Description>
  <Part Id="953562951413" UnitPrice="22.95" Quantity="1"/>
</LineItem>

UPDATE purchaseorder
  SET OBJECT_VALUE = 
      deleteXML(OBJECT_VALUE, 
                '/PurchaseOrder/LineItems/LineItem[@ItemNumber="222"]')
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING OBJECT_VALUE AS "p");

SELECT XMLQuery('$p/PurchaseOrder/LineItems/LineItem[@ItemNumber=222]'
                PASSING po.OBJECT_VALUE AS "p" RETURNING CONTENT)
  FROM purchaseorder po
  WHERE XMLExists('$p/PurchaseOrder[Reference="AMCEWEN-20021009123336171PDT"]'
                  PASSING po.OBJECT_VALUE AS "p");

XMLQUERY('$P/PURCHASEORDER/LINEITEMS/LINEITEM[@ITEMNUMBER=222]'PASSINGPO
------------------------------------------------------------------------
 
1 row selected.