ヘッダーをスキップ
Oracle® XML DB開発者ガイド
11gリリース2 (11.2)
B70200-03
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

14 PL/SQLパッケージDBMS_XMLSTORE

この章では、PL/SQLパッケージDBMS_XMLSTOREについて説明します。このパッケージは、オブジェクト・リレーショナル表のXML文書に対するデータの挿入、更新および削除に使用されます。

この章の内容は次のとおりです。

PL/SQLパッケージDBMS_XMLSTOREの概要

PL/SQLパッケージDBMS_XMLSTOREを使用すると、XMLを使用して、リレーショナル表でDML操作を実行できます。パッケージDBMS_XMLGENで生成されるマッピングと同様に正規XMLマッピングを使用し、それをオブジェクト・リレーショナルの構成に変換し、リレーショナル表に対して対応する値を挿入、更新または削除します。

パッケージDBMS_XMLSTOREの機能は、Oracle XML SQL Utility(XSU)の一部であるDBMS_XMLSAVEパッケージと類似しています。ただし、いくつか重要な違いがあります。

  • DBMS_XMLSTOREはCで作成されてカーネルにコンパイルされるため、優れたパフォーマンスが得られます。

  • DBMS_XMLSTOREは、Simple API for XML(SAX)を使用して入力XML文書を解析するため、拡張性が高く、メモリー要件が低減します。DBMS_XMLSTOREでは、CLOBおよびVARCHARに加え、XMLTypeデータを入力できます。

  • DBMS_XMLSAVEにも存在するPL/SQL関数のinsertXMLupdateXMLおよびdeleteXMLが、DBMS_XMLSTOREでは、CLOB値と文字列の他にXMLTypeインスタンスを取るように拡張されています。この結果、Oracle XML DB機能との緊密な統合が実現します。

DBMS_XMLSTOREパッケージの使用

PL/SQLパッケージDBMS_XMLSTOREを使用するには、次の手順を実行します。

  1. DBMS_XMLSTORE.newContext()関数をコールし、DML操作に使用する表名を指定してコンテキスト・ハンドルを作成します。大/小文字を区別する場合は、関数に渡す文字列を二重引用符(")で囲みます。

    デフォルトでは、XML文書は<ROW>タグで行を識別します。これは、XMLデータの生成時にDBMS_XMLGENパッケージで使用されるデフォルトと同じです。この動作は、setRowTag関数を使用してオーバーライドできます。

  2. 挿入の場合、パフォーマンスを向上させるには、列ごとにDBMS_XMLSTORE.setUpdateColumnプロシージャをコールして、挿入する列リストを設定できます。デフォルト動作では(列のリストを指定しない場合)、対応する要素がXML文書内に存在しているすべての列に値が挿入されます。

  3. 更新の場合、関数DBMS_XMLSTORE.setKeyColumnを使用して(擬似)キー列を1つ以上指定します。これらは、更新するを指定するために使用されます。SQLのUPDATE文のWHERE句でこれを行います。指定する列は、表のキーである必要はありませんが、更新する行を一意に指定する必要があります。

    たとえば、employees表のemployee_id列は、行を一意に識別します(表のキーです)。表の更新に使用するXML文書に、<EMPLOYEE_ID>2176</EMPLOYEE_ID>要素が含まれている場合、employee_id2176と等しい行が更新されます。

    パフォーマンスを向上させるために、DBMS_XMLSTORE.setUpdateColumnを使用して、update列のリストを指定することもできます。デフォルト動作では、対応する要素がXML文書に存在するsetKeyColumnによって識別される行内のすべての列が更新されます。

  4. 削除の場合、削除する行を識別するために、(擬似)キー列を指定します。これは更新する行の指定と同じ方法で行います。手順3を参照してください。

  5. PL/SQL関数のinsertXMLupdateXMLまたはdeleteXMLに文書を指定します。この手順を複数のXML文書に対して繰り返すことができます。

  6. DBMS_XMLSTORE.closeContext関数をコールしてコンテキストをクローズします。

DBMS_XMLSTOREを使用した挿入

表またはビューにXML文書を挿入するには、表名またはビュー名、および文書を指定します。DBMS_XMLSTOREによって文書が解析され、すべての値がバインドされるINSERT文が作成されます。デフォルトでは、DBMS_XMLSTOREによって、XML文書内の要素で表されるすべての列に値が挿入されます。

例14-1では、DBM_XMLSTOREを使用して、2人の新入社員に関する情報をemployees表に挿入します。この情報は、XMLデータ形式で提供されます。

例14-1 指定した列でのデータの挿入

SELECT employee_id AS EMP_ID, salary, hire_date, job_id, email, last_name
  FROM employees WHERE department_id = 30;

EMP_ID     SALARY HIRE_DATE JOB_ID     EMAIL       LAST_NAME
------ ---------- --------- ---------- ---------- ----------
   114      11000 07-DEC-94 PU_MAN     DRAPHEAL     Raphaely
   115       3100 18-MAY-95 PU_CLERK   AKHOO            Khoo
   116       2900 24-DEC-97 PU_CLERK   SBAIDA          Baida
   117       2800 24-JUL-97 PU_CLERK   STOBIAS        Tobias
   118       2600 15-NOV-98 PU_CLERK   GHIMURO        Himuro
   119       2500 10-AUG-99 PU_CLERK   KCOLMENA   Colmenares

6 rows selected.

DECLARE
  insCtx DBMS_XMLSTORE.ctxType;
  rows NUMBER;
  xmlDoc CLOB :=
    '<ROWSET>
       <ROW num="1">
         <EMPLOYEE_ID>920</EMPLOYEE_ID>
         <SALARY>1800</SALARY>
         <DEPARTMENT_ID>30</DEPARTMENT_ID>
         <HIRE_DATE>17-DEC-2002</HIRE_DATE>
         <LAST_NAME>Strauss</LAST_NAME>
         <EMAIL>JSTRAUSS</EMAIL>
         <JOB_ID>ST_CLERK</JOB_ID>
       </ROW>
       <ROW>
         <EMPLOYEE_ID>921</EMPLOYEE_ID>
         <SALARY>2000</SALARY>
         <DEPARTMENT_ID>30</DEPARTMENT_ID>
         <HIRE_DATE>31-DEC-2004</HIRE_DATE>
         <LAST_NAME>Jones</LAST_NAME>
         <EMAIL>EJONES</EMAIL>
         <JOB_ID>ST_CLERK</JOB_ID>
       </ROW>
     </ROWSET>';
BEGIN
  insCtx := DBMS_XMLSTORE.newContext('HR.EMPLOYEES'); -- Get saved context
  DBMS_XMLSTORE.clearUpdateColumnList(insCtx); -- Clear the update settings
 
  -- Set the columns to be updated as a list of values 
  DBMS_XMLSTORE.setUpdateColumn(insCtx, 'EMPLOYEE_ID'); 
  DBMS_XMLSTORE.setUpdateColumn(insCtx, 'SALARY'); 
  DBMS_XMLSTORE.setUpdateColumn(insCtx, 'HIRE_DATE');
  DBMS_XMLSTORE.setUpdateColumn(insCtx, 'DEPARTMENT_ID'); 
  DBMS_XMLSTORE.setUpdateColumn(insCtx, 'JOB_ID');
  DBMS_XMLSTORE.setUpdateColumn(insCtx, 'EMAIL');
  DBMS_XMLSTORE.setUpdateColumn(insCtx, 'LAST_NAME');

  -- Insert the doc. 
  rows := DBMS_XMLSTORE.insertXML(insCtx, xmlDoc);
  DBMS_OUTPUT.put_line(rows || ' rows inserted.');

  -- Close the context
  DBMS_XMLSTORE.closeContext(insCtx); 
END;
/

2 rows inserted.
 
PL/SQL procedure successfully completed.

SELECT employee_id AS EMP_ID, salary, hire_date, job_id, email, last_name
  FROM employees WHERE department_id = 30;

EMP_ID     SALARY HIRE_DATE JOB_ID     EMAIL       LAST_NAME
------ ---------- --------- ---------- ---------- ----------
   114      11000 07-DEC-94 PU_MAN     DRAPHEAL     Raphaely
   115       3100 18-MAY-95 PU_CLERK   AKHOO            Khoo
   116       2900 24-DEC-97 PU_CLERK   SBAIDA          Baida
   117       2800 24-JUL-97 PU_CLERK   STOBIAS        Tobias
   118       2600 15-NOV-98 PU_CLERK   GHIMURO        Himuro
   119       2500 10-AUG-99 PU_CLERK   KCOLMENA   Colmenares
   920       1800 17-DEC-02 ST_CLERK   STRAUSS       Strauss
   921       2000 31-DEC-04 ST_CLERK   EJONES          Jones

8 rows selected.

DBMS_XMLSTOREを使用した更新

DBMS_XMLSTOREパッケージを使用して既存のデータを更新(変更)するには、更新する行を指定する必要があります。SQLでは、UPDATE文のWHEREを使用してこの操作を実行します。DBMS_XMLSTOREでは、行を識別するのにまとめて使用される列ごとにsetKeyColumnプロシージャを1回ずつコールして実行します。

この列のセットは、キー列と同様に機能し、組み合せて使用することにより、更新する一意の行を指定します。ただし、(setKeyColumnとともに)使用する列は、表内のキーである必要はありません。行を一意に指定するかぎり、setKeyColumnへのコールとともに使用できます。

例14-2では、DBM_XMLSTOREを使用して情報を更新します。この例では、従業員番号188の名前が誤って「Kelly」として記録されていると仮定し、この名前を「Pat」に訂正します。employee_id列が、employees表の主キーであるため、更新用に一意の行を識別するには、employee_id列を指定するsetKeyColumnへの1回のコールで十分です。

例14-2 キー列を使用したデータの更新

SELECT employee_id, first_name FROM employees WHERE employee_id = 188;

EMPLOYEE_ID FIRST_NAME
----------- ----------
        188 Kelly
 
1 row selected.

DECLARE
  updCtx DBMS_XMLSTORE.ctxType; 
  rows NUMBER;
  xmlDoc CLOB :=
    '<ROWSET>
       <ROW>
         <EMPLOYEE_ID>188</EMPLOYEE_ID>
         <FIRST_NAME>Pat</FIRST_NAME>
       </ROW>
     </ROWSET>';
BEGIN
   updCtx := DBMS_XMLSTORE.newContext('HR.EMPLOYEES'); -- get the context
   DBMS_XMLSTORE.clearUpdateColumnList(updCtx);        -- clear update settings

   -- Specify that column employee_id is a "key" to identify the row to update.
   DBMS_XMLSTORE.setKeyColumn(updCtx, 'EMPLOYEE_ID'); 
   rows := DBMS_XMLSTORE.updateXML(updCtx, xmlDoc);    -- update the table
   DBMS_XMLSTORE.closeContext(updCtx);                 -- close the context
END;
/

SELECT employee_id, first_name FROM employees WHERE employee_id = 188;

EMPLOYEE_ID FIRST_NAME
----------- ----------
        188 Pat
 
1 row selected.

次のUPDATE文は、例14-2で使用されているDBM_XMLSTOREと同等です。

UPDATE hr.employees SET first_name = 'Pat' WHERE employee_id = 188; 

DBMS_XMLSTOREを使用した削除

削除の場合は、更新の場合と同様、削除する行を識別するキー、または疑似キー列を指定します。

例14-3 DBMS_XMLSTORE.DELETEXMLの例

SELECT employee_id FROM employees WHERE employee_id = 188;
 
EMPLOYEE_ID
-----------
        188
 
1 row selected.
 
DECLARE
  delCtx DBMS_XMLSTORE.ctxType;
  rows NUMBER;
  xmlDoc CLOB :=
    '<ROWSET>
       <ROW>
         <EMPLOYEE_ID>188</EMPLOYEE_ID>
         <DEPARTMENT_ID>50</DEPARTMENT_ID>
       </ROW>
     </ROWSET>';
BEGIN
  delCtx  := DBMS_XMLSTORE.newContext('HR.EMPLOYEES');
  DBMS_XMLSTORE.setKeyColumn(delCtx, 'EMPLOYEE_ID');
  rows := DBMS_XMLSTORE.deleteXML(delCtx, xmlDoc);
  DBMS_XMLSTORE.closeContext(delCtx);
END;
/
 
SELECT employee_id FROM employees WHERE employee_id = 188;
 
no rows selected.