【问题标题】:Oracle extract values from xmltypeOracle 从 xmltype 中提取值
【发布时间】:2013-07-06 20:18:39
【问题描述】:

这是我目前使用的代码:

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 中只有一个数据,而且我只会有 nameage 标签。

下面的代码应该用于保存到 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;

/ 任何更好的方法表示赞赏.. 谢谢

【问题讨论】:

    标签: oracle plsql extract xmltype


    【解决方案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;
    

    如果你有nameage,或者两者都有,或者两者都没有(其中“工作”意味着至少没有错误),这将起作用。如果您确实有不止一行,它将连接结果,因此对于您的原始数据,l_name 将是 aabbbl_age 将是 2025。这可能不是您所期望的。

    【讨论】:

    • 谢谢..我需要在此之后使用不为null的局部变量,以包含在where条件中,即我需要使用类似“select * from test where name = l_name”,如果 l_name 不为 null,或者如果 l_age 不为 null,我需要在单个查询中使用“select * from test where age = l_age”。
    • @ajmalmhd04 - 你可以做where (l_name is not null and name = l_name) or (l_age is not null and age = l_age),这样可以避免隐式数据类型转换;或将上面块中间的end if; if 更改为elsif 并将两个部分分配给相同的字符串变量。
    • 是的.. 已经完成了。干杯:) !!现在一切似乎都很好。
    猜你喜欢
    • 2019-08-19
    • 1970-01-01
    • 2020-02-08
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    相关资源
    最近更新 更多