2

私はこのXMLを持っています。

<a>
   <b>b1</b>
   <c>c1</c>
   <b>b2</b>
   <c>c2</c2>
</a>

PL\SQL を使用して要素 'b' と 'c' の値を抽出できるようにしたいと考えています。私はオラクル10gを使用しています。

これまでのところ、私はこれを持っています、

  SELECT   XML.b                    
       , XML.c
    FROM XMLTable (
           '/a' PASSING p_xml
              COLUMNS
                 b            VARCHAR(2) PATH 'b/.'
               , c            VARCHAR(2) PATH 'c/.'
    ) XML

しかし、私はこのエラーを受け取り続けます:

19279. 00000 -  "XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence" 
*Cause:    The XQuery sequence passed in had more than one item.
*Action:   Correct the XQuery expression to return a single item sequence.

それから私はこれを試しました:

  SELECT   XML.b                    
         , XML1.c
    FROM XMLTable (
           '/a/b' PASSING p_xml
              COLUMNS
                 b            VARCHAR(2) PATH '.'
    ) XML,
        XMLTable (
           '/a/c' PASSING p_xml
              COLUMNS
                 c            VARCHAR(2) PATH '.'
    ) XML1

しかし、結果は次のとおりでした。

b1,c1
b1,c2
b2,c1
b2,c2

私だけが欲しい時: b1 c1 b2 c2

皆さん、私を助けてくれませんか?

4

2 に答える 2

1

私はそれを実行しませんでしたが、以下のコードを見る限り、動作するはずです。

DECLARE
vs_Xml VARCHAR2(32000):= '<INPUT>
  <A>
    <B>1</B>
  </A>
  <A>
    <B>2</B>
  </A>
</INPUT>';

vx_ParameterList   XMLTYPE;
vx_Parameter       XMLTYPE;
vn_ParameterIndex  NUMBER;
vs_Key             VARCHAR2(64);
vs_XPath           VARCHAR2(255);
vs_Value           VARCHAR2(10000);

BEGIN
vx_ParameterList := xmltype(vs_Xml);
vn_ParameterIndex := 1;
vs_XPath := '/INPUT/A'; 

WHILE vx_ParameterList.existsNode(vs_XPath || '[' || vn_ParameterIndex || ']') = 1 LOOP
  vx_Parameter := vx_ParameterList.extract(vs_XPath || '[' || vn_ParameterIndex || ']');

  vs_Value := vx_Parameter.extract('//B/text()').GetStringVal();
  vn_ParameterIndex := vn_ParameterIndex + 1;

  dbms_output.put_line(vs_Value);
END
于 2015-02-25T12:33:20.570 に答える
1

コマンドで xquery 式を調整する必要がありますXMLTABLE。基本的な考え方は、それぞれがデータベース レコードの列にマップできる xml レコードのストリームを生成することです。

元の xml の障害は、xpath 軸がすべてのxml レコード/aのコンテンツを返すことです (ずさんな言い回しで)。

/a解決策は、xml レコードを 1 つずつ配信する反復子を構築することです(技術的には、合成x要素にラップされます)。

以下は、sqlplus から発行できます。

      SELECT   myxml.b
           ,   myxml.c                            
        FROM XMLTable (
'for $i in (1, let $x := fn:count(/a/b) return $x )
 let $b := /a/b[$i], $c := /a/c[$i]
 return <x>
           <b>{$b}</b>
           <c>{$c}</c>
        </x>
' PASSING XMLTYPE(
'<a>
   <b>b1</b>
   <c>c1</c>
   <b>b2</b>
   <c>c2</c>
</a>')
                  COLUMNS
                     b            VARCHAR(2) PATH '/x/b'
                   , c            VARCHAR(2) PATH '/x/c'
        ) myxml
;

アップデート

b任意の数の/子を許可するためにc、次の行

for $i in (1, let $x := fn:count(/a/b) return $x )

オリジナルを置き換えます

for $i in (1, 2)

上記の式で。

参照

XQuery 構文の詳細については、W3c 仕様(いわゆる FWLOR 式の構文ドキュメントへのディープ リンク) を参照してください。

于 2015-02-25T14:05:53.030 に答える