2016-12-20 16 views
1

私のテーブルの列の1つに格納されているXMLデータからタグに対応するデータを抽出するのに助けが必要です。以下は私のテーブルのサンプルXMLデータです。タグ 'REQUESTTYPE'に対応する値を抽出する必要があります。Oracleのxmlデータから値を抽出

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE VXIN SYSTEM "VXInData.dtd"> 
<VXIN> 
<REQUESTS> 
<REQUEST> 
<REQUESTTYPE>ADD</REQUESTTYPE> 
<REQUESTNUMBER>12345</REQUESTNUMBER> 
<ID>1234567</ID> 
<ACCESSLIST> 
<ACCESS> 
<ACCESSLEVEL> 
<AID>123789</AID> 
</ACCESSLEVEL> 
<PERSONNEL> 
<REQUESTEDFOR> 
<UID>13579</UID> 
<FIRSTNAME>MOBY</FIRSTNAME> 
</REQUESTEDFOR> 
</PERSONNEL> 
</ACCESS> 
</ACCESSLIST> 
</REQUEST> 
</REQUESTS> 
</VXIN> 

ご協力いただきまして誠にありがとうございます。それを行うには

+0

あなたの期待される出力が何であるか、テーブルスキーマの定義も表示してください。 – OldProgrammer

+0

私はそれがかなりよく指定されていると思います。 – Rene

+0

私は、上記のxmlの 'ADD'を返すクエリを探しています。私のテーブルはxml列以上で、その他の日付属性はほとんどありません。 – AsteriK

答えて

1

EXTRACTVALUE機能は推奨されていません。下位互換性のために引き続きサポートされています。ただし、代わりにXMLTABLEファンクションまたはXMLCASTファンクションとXMLQUERYファンクションを使用することをお薦めします。

SELECT XMLQUERY('/VXIN/REQUESTS/REQUEST/REQUESTTYPE/text()' 
    PASSING XMLTYPE('<?xml version="1.0" encoding="UTF-8"?> 
<VXIN> 
<REQUESTS> 
<REQUEST> 
<REQUESTTYPE>ADD</REQUESTTYPE> 
<REQUESTNUMBER>12345</REQUESTNUMBER> 
<ID>1234567</ID> 
<ACCESSLIST> 
<ACCESS> 
<ACCESSLEVEL> 
<AID>123789</AID> 
</ACCESSLEVEL> 
<PERSONNEL> 
<REQUESTEDFOR> 
<UID>13579</UID> 
<FIRSTNAME>MOBY</FIRSTNAME> 
</REQUESTEDFOR> 
</PERSONNEL> 
</ACCESS> 
</ACCESSLIST> 
</REQUEST> 
</REQUESTS> 
</VXIN>') RETURNING CONTENT) AS REQUESTTYPE 
FROM dual; 

しかし、あなただけの1の値XMLTABLE(以上のものを抽出したい場合には:あなたもXMLQUERYを使用することができ、正常に動作しますxmltableEXTRACTVALUE

機能を参照してください、詳細についてはXMLTABLE、XMLCAST、およびXMLQUERYを参照してください。 )より良いはずです。

+0

ありがとうWernfried、上記のソリューションは完璧に働いた! – AsteriK

2

一つの方法:

declare 
    l_xml   xmltype; 
    l_requesttype varchar2(30); 
begin 
    l_xml := xmltype('<?xml version="1.0" encoding="UTF-8"?> 
<VXIN> 
<REQUESTS> 
<REQUEST> 
<REQUESTTYPE>ADD</REQUESTTYPE> 
<REQUESTNUMBER>12345</REQUESTNUMBER> 
<ID>1234567</ID> 
<ACCESSLIST> 
<ACCESS> 
<ACCESSLEVEL> 
<AID>123789</AID> 
</ACCESSLEVEL> 
<PERSONNEL> 
<REQUESTEDFOR> 
<UID>13579</UID> 
<FIRSTNAME>MOBY</FIRSTNAME> 
</REQUESTEDFOR> 
</PERSONNEL> 
</ACCESS> 
</ACCESSLIST> 
</REQUEST> 
</REQUESTS> 
</VXIN>'); 

    select x.* 
    into l_requesttype 
    from xmltable('/VXIN/REQUESTS/REQUEST' passing l_xml columns requesttype varchar2(30) path 'REQUESTTYPE') x; 

    dbms_output.put_line(l_requesttype); 
end; 

データベースがそれにアクセスすることはできませんので、私はDTDへの参照を削除した見ることができるように。 このコードをDTD参照で実行するには、パーサーに検索されないように指示することができます。

declare 
    l_xml   xmltype; 
    l_requesttype varchar2(30); 
begin 

    execute immediate 'alter session set events =''31156 trace name context forever, level 2'''; 

    l_xml := xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE VXIN SYSTEM "VXInData.dtd"> 
<VXIN> 
<REQUESTS> 
<REQUEST> 
<REQUESTTYPE>ADD</REQUESTTYPE> 
<REQUESTNUMBER>12345</REQUESTNUMBER> 
<ID>1234567</ID> 
<ACCESSLIST> 
<ACCESS> 
<ACCESSLEVEL> 
<AID>123789</AID> 
</ACCESSLEVEL> 
<PERSONNEL> 
<REQUESTEDFOR> 
<UID>13579</UID> 
<FIRSTNAME>MOBY</FIRSTNAME> 
</REQUESTEDFOR> 
</PERSONNEL> 
</ACCESS> 
</ACCESSLIST> 
</REQUEST> 
</REQUESTS> 
</VXIN>'); 

    select x.* 
    into l_requesttype 
    from xmltable('/VXIN/REQUESTS/REQUEST' passing l_xml columns requesttype varchar2(30) path 
        'REQUESTTYPE') x; 

    dbms_output.put_line(l_requesttype); 
end; 
+0

ルネありがとう、上記のブロックが動作します!私はテーブルからxmlデータを直接読み込み、目的の出力を得るために使うことができる1行のクエリがありますか?私が求めている理由は、テーブル内の複数のレコードに対して、where句を満たしていれば、この操作を行う必要があるからです。 – AsteriK

+0

単に 'xmltype()'を置き換えてください。 'l_xml'をあなたのカラム名で置き換えます。 –

0

Wernfriedによって投稿されたソリューションに基づいて、私はテーブルから値を読み取るために少しクエリをチューニングしました。以下は私の最終的な質問です:

select XMLQUERY('/VXIN/REQUESTS/REQUEST/REQUESTTYPE/text()' passing xmltype(XML_DATA) RETURNING CONTENT) AS REQUESTTYPE from table; 
+0

'XML_DATA'列のデータ型は何ですか? 'XMLTYPE'の場合、' xmltype(XML_DATA) 'を作る必要はありません。単に' XML_DATA'を使うだけです。データ型がVARCHAR2またはCLOBの場合は、 'xmltype(XML_DATA)'が必要です –

+0

はい@Wernfried Domscheit、表内のXML_DATAはCLOBデータ型です – AsteriK

関連する問題