2017-02-10 3 views
1

私のXMLは次のようになりますどのようにPL/SQLでXMLをループを実行するには

<root> 
    <row> 
    <grade>A</grade> 
    <Employee> 
     <Name>ROBERT SUKIMIN</Name> 
     <company>ABC</company>  
    </Employee> 
    <Group>117761020</Group> 
    <Designation>2014-03-21</Designation> 
    <Company_code>5813044</Company_code> 
    </row> 
    <row> 
    <grade>B</grade> 
    <Employee> 
     <Name>CECIL PAINEM</Name> 
     <company>XYZ</company> 
    </Employee> 
    <Employee> 
     <Name>SUGRIWO</Name> 
     <company>BCA</company> 
    </Employee> 
    <Group>40560050</Group> 
    <Designation>2012-05-03</Designation> 
    <Company_code>0</Company_code> 
    </row> 
</root> 

私は出力をしたいと思います:

A Robert Sukimin ABC 117761020 2014-03-21 5813044 
B CECIL PAINEM XYZ 405600 2012-05-03 0 
B SUGRIWO BCA 405600 2012-05-03 0 

どのようにXMLでのループとしてOracleテーブルにデータを挿入最小限のパフォーマンスの問題、1000レコードを前提としていますか?

+0

なぜPL/SQLですか?なぜプレーンSQLではないのですか? –

+0

あなたがコードしたものを投稿し、何が間違っているのか記述できますか? – laylarenee

+0

@AlexPooleとOP、なぜSQL?あらゆる汎用言語(Java、C#、PHP、Python、VB)はXML文書を解析し、XPathやXSLTのような他の特殊目的コードを呼び出すことができます。私たちが愛している限り、SQLは特別な目的の言語です。消して、保存されたproc(gasp)(一気に)と電子メールを送信しようとしているポスターを見つける! – Parfait

答えて

3

複数のXMLTableレベルを使用してこれを行うことができます。 1つのXMLTableは、等級、グループ、指定などを取得し、現在の行もXMLTypeオブジェクトとして取得します。 2番目のXMLTableは、抽出された行からすべての従業員名を抽出します。取得

with t (xml) as (
    select xmltype('<root> 
    <row> 
    <grade>A</grade> 
    <Employee> 
     <Name>ROBERT SUKIMIN</Name> 
     <company>ABC</company>  
    </Employee> 
    <Group>117761020</Group> 
    <Designation>2014-03-21</Designation> 
    <Company_code>5813044</Company_code> 
    </row> 
    <row> 
    <grade>B</grade> 
    <Employee> 
     <Name>CECIL PAINEM</Name> 
     <company>XYZ</company> 
    </Employee> 
    <Employee> 
     <Name>SUGRIWO</Name> 
     <company>BCA</company> 
    </Employee> 
    <Group>40560050</Group> 
    <Designation>2012-05-03</Designation> 
    <Company_code>0</Company_code> 
    </row> 
</root>') from dual 
) 
select x.grade, y.name, y.company, x.group_num, x.designation, x.company_code 
from t 
cross join xmltable ('/root/row' 
    passing t.xml 
    columns grade varchar2(1) path 'grade', 
    row_xml xmltype path '.', 
    group_num number path 'Group', 
    designation varchar2(10) path 'Designation', 
    company_code number path 'Company_code' 
) x 
cross join xmltable ('/row/Employee' 
    passing x.row_xml 
    columns name varchar2(30) path 'Name', 
    company varchar2(5) path 'company' 
) y; 

G NAME       COMPA GROUP_NUM DESIGNATIO COMPANY_CODE 
- ------------------------------ ----- ---------- ---------- ------------ 
A ROBERT SUKIMIN     ABC 117761020 2014-03-21  5813044 
B CECIL PAINEM     XYZ  40560050 2012-05-03   0 
B SUGRIWO      BCA  40560050 2012-05-03   0 

あなたがinsert into some_table (column1, column2, ...) select ...で別のテーブルにそのクエリの結果を挿入することができCTEで

は自分のベースXMLを生成します。

一般に、値が表から来る場合は、これを実現するためにPL/SQLは必要ありません。

XMLをPL/SQL変数に設定している場合、たとえば次のようになります。 Webサービスコールから、テーブルから直接選択する代わりに、その変数を使用して同じことを実行できます。それでもターゲット表に直接挿入できます。この例では、Webサービスの結果を持つローカルPL/SQL変数がl_xmlと呼ばれ、XMLType型であると想定しています。あなたは明らかにあなた自身の本当のものを使用したいので、テーブル名とカラム名を発明:

declare 
    l_xml XMLType; 
    ... 
begin 
    -- call web service to populate l_xml 
    ... 

    insert into you_table(grade, name, company, group_num, designation, company_code) 
    select x.grade, y.name, y.company, x.group_num, x.designation, x.company_code 
    from xmltable ('/root/row' 
    passing l_xml -- your local XMLType variable 
    columns grade varchar2(1) path 'grade', 
     row_xml xmltype path '.', 
     group_num number path 'Group', 
     designation varchar2(10) path 'Designation', 
     company_code number path 'Company_code' 
) x 
    cross join xmltable ('/row/Employee' 
    passing x.row_xml 
    columns name varchar2(30) path 'Name', 
     company varchar2(5) path 'company' 
) y; 

    ... 
end; 

あなたはCLOBにWebサービスの結果を取得している場合は、コールの一部としてそれを変換することができます:

... 
    from xmltable ('/root/row' 
    passing XMLType(l_clob) -- your local CLOB variable 
    ... 

ループを使用する必要はありません。 は、同じクエリにカーソルループを使用して、各結果を1つずつテーブルに挿入することができますが、それは利点がないために遅くなります。

+0

あなたの助けをありがとうが、ケースはどのようにそのループ1000レコードを前提とした最小限のパフォーマンスの問題でOracleの表にデータを挿入しますか? – user2728057

+0

@ user2728057 - そのクエリの結果を表に挿入するだけで済みます。なぜ単純な 'insert ... select'より効率の低いループを使いたいのですか?1000 XMLレコードはどこから来ていますか、別のテーブル、ファイル.... –

+0

私は私のストアドプロシージャからWebサービスを呼び出し、XML応答を取得します。私は、XMLを解析し、Oracleのテーブルに値を挿入したい。 – user2728057

関連する問題