在存储过程中循环遍历Xmltype

时间:2015-03-11 20:54:29

标签: sql xml oracle stored-procedures plsql

我正在尝试解析/循环遍历简单的xml以捕获单个值,并在将来使用它做一些事情。

此代码有效......有点 - 请参阅代码内注释

Declare 
    /* 2-item xml */
    x nvarchar2(1000) := '<values><value>1,"rrr|</value><value>2</value></values>';
    xt XmlType;
    /* expect c = 2 in the end */
    c number := 0;
Begin
   xt := XmlType.CreateXML(x);

   for rec in (SELECT extractvalue(value(xTbl), '/values/value/text()') val FROM TABLE(XMLSEQUENCE(EXTRACT(xt, '//values/value'))) xTbl)
   loop
       /* This obviously runs two times but prints nothing */
       dbms_output.put_line(rec.val); 
       /* this works well */
       c := c + 1;
   end loop;
   /* This works correctly */
   dbms_output.put_line('Count: ' || c); 
End;

如您所见,我获得了正确的循环次数,但rec.val中没有任何内容。任何人吗?

2 个答案:

答案 0 :(得分:2)

不推荐使用EXTRACTVALUE。相反,请使用XMLTABLE

SQL> SELECT xtbl.val 
FROM XMLTABLE('values/value'
        PASSING XMLTYPE('<values><value>1,"rrr|</value><value>2</value></values>')
        COLUMNS val VARCHAR2(10) PATH '.'
        ) xtbl;

VAL
----------
1,"rrr|
2

在光标中使用此查询。

declare 
    x nvarchar2(1000) := '<values><value>1,"rrr|</value><value>2</value></values>';
    xt XmlType;
    c number := 0;
Begin
   xt := XmlType.CreateXML(x);

   for rec in (
    SELECT xtbl.val 
        FROM XMLTABLE('values/value'
            PASSING xt
            COLUMNS val VARCHAR2(10) PATH '.'
            ) xtbl
            )
   loop
       dbms_output.put_line(rec.val); 
       c := c + 1;
   end loop;
   dbms_output.put_line('Count: ' || c); 
End;
/


1,"rrr|
2
Count: 2

PL/SQL procedure successfully completed.

答案 1 :(得分:1)

嗨,改变你不需要提取值中的整个路径...

将其更改为以下内容,它应该适合您

for rec in (SELECT extractvalue(value(xTbl), '/value') val FROM TABLE(XMLSEQUENCE(EXTRACT(xt, '//values/value'))) xTbl)

希望有所帮助