web-dev-qa-db-ja.com

ストアドプロシージャのOracleテーブルにXML入力を挿入する最良の方法は何ですか?

XML入力(Clobタイプ)があり、データをテーブルに挿入するストアード・プロシージャーを書きたいのですが。私のXML構造は次のようなものです:

<rowset>
    <row>
        <name>tom</name>
        <family>mack</family>
        ....
    </row> 
    <row>
        <name>marry</name>
        <family>skot</family>
        ....
    </row> 
    ...
</rowset>

オラクルがこれを処理するためにくれた多くのオプションの在庫があります。 extractvalue and XMLSequence-の使用DBMS_XMLDOM- DBMS_XMLStoreの使用またはその他の多くのオプション。

使用するパフォーマンスやリソースに応じてどちらが良いか知りたい。入力XMLは通常50KB未満です。

2
rahim asgari

XMLTABLE を使用して、XMLデータをSQLで直接クエリできます。

SQL> VARIABLE xml VARCHAR2(4000);
SQL> BEGIN :xml :=
  2  '<rowset>
  3       <row>
  4           <name>tom</name>
  5           <family>mack</family>
  6       </row>
  7       <row>
  8           <name>marry</name>
  9           <family>skot</family>
 10       </row>
 11   </rowset>';
 12  END;
 13  /

PL/SQL procedure successfully completed

SQL> SELECT x.*
  2    FROM XMLTable('for $i in /rowset/row return $i'
  3                    passing XMLTYPE(:xml) columns
  4                       name VARCHAR2(200) path 'name',
  5                       family VARCHAR2(200) path 'family'
  6                  ) x;

NAME    FAMILY
------- -------
tom     mack
marry   skot

XMLSequence および EXTRACT を使用することもできます( this SO question)を参照 例)ただし、ドキュメントに記載されているように、これらの関数は廃止されています。

別のオプションは DBMS_XMLSTORE 、あまりカスタマイズすることはできませんが(入力xmlタグと出力列名を完全に一致させる必要があります):

SQL> CREATE TABLE my_table ("name" VARCHAR2(10), "family" VARCHAR2(10));

Table created

SQL> DECLARE
  2     l_ctx  dbms_xmlstore.ctxtype;
  3     l_rows NUMBER;
  4  BEGIN
  5     l_ctx := dbms_xmlstore.newcontext('MY_TABLE'); -- Get saved context
  6     dbms_xmlstore.clearUpdateColumnList(l_ctx); -- Clear the update settings
  7  
  8     -- Set the columns to be updated/inserted as a list of values
  9     dbms_xmlstore.setUpdateColumn(l_ctx, 'name');
 10     dbms_xmlstore.setUpdateColumn(l_ctx, 'family');
 11     -- Set ROW tag
 12     dbms_xmlstore.setRowTag(l_ctx, 'row');
 13  
 14    -- Insert the doc.
 15    l_rows := DBMS_XMLSTORE.insertXML(l_ctx, :xml);
 16    DBMS_OUTPUT.put_line(l_rows || ' rows inserted.');
 17  
 18    -- Close the context
 19    DBMS_XMLSTORE.closeContext(l_ctx);
 20  
 21  END;
 22  /

2 rows inserted.

PL/SQL procedure successfully completed

SQL> select * from my_table;

name       family
---------- ----------
tom        mack
marry      skot

パフォーマンスに関して、どちらのオプションが速いかわかりません。これは確かにデータに依存します。ベンチマークを行う必要があります。

3
Vincent Malgrat