2

Web サービスから取得し、PL/SQL の XMLTYPE 変数に格納した次の XML 構造があります。

     <results>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername>
        </return>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername></return>
        <return>
            <customerid>93</customerid>
            <customername>Test2</customername>
        </return>
        <return>
            <customerid>96</customerid>
            <customername>Test3</customername>
        </return>
     </results>

私が使用している Web サービスは柔軟性がないため、customerid を 1 回だけ出現させ、対応する値とともに表示する必要があることを指定する方法はありません。それを念頭に置いて、PL/SQL を使用してこの XML ドキュメントを解析し、各顧客 ID の最初の出現のみを取得するにはどうすればよいでしょうか?

たとえば、上記を解析すると次のように返されます。

       127 Test1
       93 Test2
       96 Test3

私のアイデアは、XML の解析を開始し、顧客 ID が存在するかどうか (既に画面に出力されているかどうか) について、空の配列に対してクエリを実行することでした。そうでない場合は、顧客 ID を一致する名前で画面に出力し、顧客 ID を配列に追加します。これは、次回その XML タグがスキップされ、次のタグに移動することを意味します。少なくともそれは PHP で実行できることですが、残念ながら今回は PL/SQL を使用する必要があります。

PL/SQLでこれを行う最も効率的な方法についてのアイデアはありますか?

乾杯、

ジェイソン

追加: 必要に応じて、PL/SQL を使用してその場で XML ドキュメントを生成しているため、XML ドキュメントの構造を変更できます。

4

1 に答える 1

3

すべてのノードをデータセットに抽出し、個別の値を選択します。

SQLフィドル

with params as (
  select 
    xmltype('  
     <results>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername>
        </return>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername></return>
        <return>
            <customerid>93</customerid>
            <customername>Test2</customername>
        </return>
        <return>
            <customerid>96</customerid>
            <customername>Test3</customername>
        </return>
     </results>
   ') p_xml 
 from dual
) 
select 
  distinct customer_id, customer_name 
from 
  XMLTable(
    '
      for $i in $doc/results/return     
        return $i
    '
    passing (select p_xml from params) as "doc"
    columns
      customer_id   number         path '//customerid',
      customer_name varchar2(4000) path '//customername'
  )

解析する別の方法:

SQLフィドル

with params as (
  select 
    sys.xmltype('  
     <results>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername>
        </return>
        <return>
            <customerid>127</customerid>
            <customername>Test1</customername></return>
        <return>
            <customerid>93</customerid>
            <customername>Test2</customername>
        </return>
        <return>
            <customerid>96</customerid>
            <customername>Test3</customername>
        </return>
     </results>
   ') p_x 
 from dual
) 
select distinct
 extractvalue(column_value, '//customerid') customer_id,
 extractvalue(column_value, '//customername') customer_name
from 
  table(XMLSequence((select extract(p_x, '/results/return') x from params)))

必要に応じて、データセットから XML を再構築します。

SQLフィドル

with params as (
  select 
    sys.xmltype('  
      -- same XML text as in previous examples ------- 
   ') p_x 
 from dual
) 
select 
  XMLElement("results",
    XMLAgg(
      XMLElement("return",
        XMLConcat(
          XMLElement("customerid", customer_id),
          XMLElement("customername", customer_name)
        )
      )
    )           
  ).getclobval()  
from (  
  select distinct
   extractvalue(column_value, '//customerid') customer_id,
   extractvalue(column_value, '//customername') customer_name
  from 
    table(XMLSequence((select extract(p_x, '/results/return') x from params)))
)
于 2013-08-09T16:31:51.667 に答える