2017-08-24 9 views
1

が誰かは、Oracle XMLType列からデータを取得で私を助けることができるRetreving XML要素

drop table xml_analysis; 
create table xml_analysis(id number,soft_attributes XMLType); 
create table xml_softattributes(id number,soft_attributes varchar2(200)); 
INSERT INTO xml_analysis VALUES 
    (  1, XMLType(
       '<softattributes> 
       <attr1>ABC</attr1> 
       <attr2>XYZ</attr2> 
       <attr3>PQR</attr3> 
       </softattributes> 
       ')); 
    insert into xml_softattributes values(1,'attr1'); 
    insert into xml_softattributes values(1,'attr2'); 
    insert into xml_softattributes values(1,'attr3'); 
  1. 表のxml_analysisは私が
  2. 表のxml_softattributesを知らないその属性はXMLType列を含み、 xml_analysisテーブルのXMLType列に存在するsoftattributes(ないのXPath)のリストを含む
  3. テーブルは、IDに基づいて接合され

今、私の問題は、テーブルxml_softattributesを使用してxml_analysisテーブルからデータを動的に取得することです。どうすればいいですか?

出力は私が動的な文字列を使用して実行されると考えることができ

Softattribute Value 
======================= 
    attr1  ABC 
    attr2  XYZ 
    attr3  PQR 

可能なソリューションを必要として、しかし、私は、ダイナミックな文字列クエリがデータを取得する必要はありません。

+0

属性名が石で設定されていますか(attr1、attr2、および、attr2のみです) attr3'')、あるいはそれらを恣意的に許可する必要があり、 'xml_softattributes'の値に基づいて検索しますか?それが前者の場合は、静的コードで行うことができます。さもなければ動的コードが必要になるでしょうが(おそらく)、なぜあなたが '' attr1''と '' ABC''、 '' attr2''と '' attr2''というより一般的なXML構造を持たないのか、 XYZ 'などは、同じタイプのノードの「値」です。いずれにしても、これはEAVモデルのようなものです...最初に修正する必要がありますか? – mathguy

+0

@mathguy:いいえ、属性名のパターンはありません。xml_softattributesテーブルの値に基づいて、何でも構いません。reqは、特定のCSVのソフトアトリビュートのセットです。テーブルに列を作成します。したがって、このxml_softattributesテーブルは、xml_analysisテーブルに動的に基づいてxmlを作成して作成します。その後、いくつかのレポートに対してこの属性を取得する必要があります。ただし、構造はattribute_nameとvalueになります。あなたは、XMLデータがそのように構成されている場合は、使用することができます:あなたのコメントでは非常に最後の文章は私が/示唆しています正確に何である - 我々はまた、「 ATTR1 ABC」 –

+0

@GauravSoniのようなXMLデータを格納することができます可能なすべての属性の名前を事前に知らなくてもXMLTYPEからXMLTYPEを抽出する 'XMLTABLE'関数、 UNPIVOTは必要ありませんが、データはすでに必要な列形式で抽出されています。 – mathguy

答えて

5

existsNodeextractの組み合わせは、次のように使用できます。

SELECT b.SOFT_ATTRIBUTES, 
    CASE 
    WHEN existsNode (a.soft_attributes ,'/*/' 
     ||b.SOFT_ATTRIBUTES) = 1 
    THEN a.soft_attributes.extract('/*/' 
     ||b.SOFT_ATTRIBUTES 
     ||'/text()').getStringVal() 
    END value 
FROM xml_analysis a, 
    xml_softattributes b 
WHERE a.id = b.id; 

*任意の子ノードと一致するワイルドカードとして使用されています。たとえば、/ PO/*/STREETは、PO要素の孫であるストリート要素に一致します。

出力:

attr1 ABC 
attr2 XYZ 
attr3 PQR 
3

属性のセットが固定されている場合('attr1', 'attr2', 'attr3')は、その後、あなたはXML構造からデータを抽出することができ、その後、アンピボット。その後、通常の方法で他のテーブルに参加することができます。

select id, softattribute, value 
from (
     select x.id, xt.attr1, xt.attr2, xt.attr3 
     from xml_analysis x, 
       xmltable('/softattributes' 
       passing x.soft_attributes 
       columns 
        attr1 varchar2(100) path 'attr1', 
        attr2 varchar2(100) path 'attr2', 
        attr3 varchar2(100) path 'attr3' 
      ) xt 
    ) 
unpivot (value 
      for softattribute in (attr1 as 'attr1', attr2 as 'attr2', attr3 as 'attr3') 
     ) 
; 

ID SOFTATTRIBUTE VALUE 
-- ------------- ----- 
1 attr1   ABC 
1 attr2   XYZ 
1 attr3   PQR 

属性のセットは、データのみを検査することで知られている場合、UNPIVOTは動作しません - とPATHはあなたが書くときに知られている文字列リテラルでなければなりませんので、XMLTABLEは、いずれかの動作しません。コード(または動的クエリ作成プロセスに知られています)は、実行時には学習できません。

これが問題になる場合は、XML構造の再検討が必要な場合があります。 'attr1'などは値と同じようにラベルではなく値でなければなりません。