3

これは私が現在使用しているコードです:

SET serveroutput ON
CREATE OR REPLACE
PROCEDURE test_proc(i_xml varchar2)
IS

l_name VARCHAR2(20);
l_age NUMBER;
l_xml xmltype;
BEGIN
l_xml := xmltype(i_xml);


FOR x IN
(SELECT VALUE(p) col_val
FROM TABLE(XMLSEQUENCE(EXTRACT(l_xml, '/ROWSET/ROW'))) p
)
LOOP

     IF x.col_val.existSNode('/ROW/name/text()') > 0 THEN
          l_name:= x.col_val.EXTRACT('/ROW/name/text()').getstringVal();
     END IF;
     IF x.col_val.existSNode('/ROW/age/text()') > 0 THEN
          l_age := x.col_val.EXTRACT('/ROW/age/text()').getstringVal();
     END IF;
end loop;

end;
/
BEGIN
test_proc('<ROWSET>
<ROW>
<name>aa</name>
<age>20</age>
</ROW>
<ROW>
<name>bbb</name>
<age>25</age>
</ROW>
</ROWSET>');
END;
/

上記のコードは、xml を使用して既存のノード値を抽出し、特定のローカル変数に保存します。複数のデータセットのケースで使用されており、正常に機能しています。「for x ループ」なしで同じものを使用できるかどうかを知りたかったのです。これ以降、i_xml にはデータが 1 つしかなく、 nameor agetags のいずれかしかないためです。

次のコードは、上で使用したような「ループ」メソッドを使用せずに l_name または l_age に保存するために使用する必要があります。

<ROWSET>
<ROW>
    <name>aa</name>
</ROW>
</ROWSET>

また

<ROWSET>
<ROW>
    <age>18</age>
</ROW>
</ROWSET>

/そして、私は以下を使用してみました:

SELECT
     CASE
          WHEN VALUE(p).existsNode('/ROW/name/text()') = 1
          THEN p.EXTRACT('/ROW/name/text()').getstringVal()
          WHEN VALUE(P).existsNode('/ROW/age/text()') = 1
          THEN p.EXTRACT('/ROW/age/text()').getstringVal()
     END
INTO l_new
FROM TABLE(xmlsequence(EXTRACT(l_xml, '/ROWSET/ROW'))) p;

/ より良い方法は大歓迎です..ありがとう

4

1 に答える 1

5

1つしかないことが本当に確実な場合は、次のROWことができます。

begin
  l_xml := xmltype(i_xml);
  if l_xml.existsnode('/ROWSET/ROW/name') > 0 then
    l_name := l_xml.extract('/ROWSET/ROW/name/text()').getstringval();
  end if;
  if l_xml.existsnode('/ROWSET/ROW/age') > 0 then
    l_age := l_xml.extract('/ROWSET/ROW/age/text()').getnumberval();
  end if;
end;

nameor 、または両方がある場合、またはどちらでもない場合に機能しますage(「機能」は、少なくともエラーにならないことを意味します)。複数の行があった場合、結果が連結されるため、元のデータでl_nameaabbb、 、およびl_ageになります2025。これはあなたが期待するものではないかもしれません。

于 2013-07-09T10:45:27.267 に答える