在复杂的PL / SQL中使用Oracle XMLElement

时间:2012-10-30 07:02:46

标签: xml oracle plsql oracle10g

使用Oracle 10gR2,我需要从存储在标准关系表中的数据中生成类似下面的伪示例。

<product>
  <productName>p1</productName>
  <productNumber>100</productNumber>
  <productObsoletes>
     <obsoletedProduct label=1>50</obsoletedProduct>
     <obsoletedProduct label=2>55</obsoletedProduct>
  </productObsoletes>
</product>

问题是,我需要使用包含数据的行做决策。我的数据库(我继承了)设计很差,决定行包含所需的逻辑很复杂。不幸的是,重新设计数据库不是一种选择。我在这里大大简化了逻辑,所以不是可以使用简单连接或where子句的情况。数据的层次结构和数据格式定义都很复杂。

在伪代码中,过度简化的决策看起来像是:

BEGIN
   --select our basic attributes

     select XMLEMENT("product",XMLELEMENT("productName",name),XMLELEMENT("productNumber",product_number))
into xml_output from products where product_number = 100;

   --now process our obsolete rows
   select XMLELEMENT("productObsoletes") into xml_output from dual;
   FOR c_row in (select * from product_obsoletes where id=100)
   LOOP
       IF c_row.display = 'YES' THEN
        select XMLELEMENT("obsoletedProduct", XMLATTRIBUTES(c_row.label as "label"), c_row.obsoleted_product_id) into xml_output from dual;
       ELSE
          CONTINUE;
       END IF;
   END LOOP;
END;

显然,这不起作用。首先,XMLElement总是打开一个结束标记,所以除非你可以制定一个包含所有元素的select语句,否则它不起作用。其次,在这个例子中,我将覆盖以前的XMLELEMENT输出。我无法连接,因为XMLELEMENT已经关闭了标签。

此时我能想到的唯一解决方案是在不同的VARCHARS中选择我需要的各种XMLElement部分,然后使用字符串操作函数找到插入各个部分的正确位置。丑陋的资本-U。

还有其他解决方案吗?是否有一种方法可以阻止XMELEMENT关闭标记,以便您可以使用复杂的循环逻辑?还是另一个Oracle构造,它允许我实现构建这个XML的目标,而不必使用单个select语句?

我的最后一种方法是使用其他语言(如Java或Perl)进行XML生成,在那里我可以简单地获取数据,然后在那里进行复杂的处理和XML生成。但是,我更喜欢只有一个SQL函数,它会将正确的XML作为字符串返回,所以如果可以在PL / SQL中执行它,那么这将是我的首选路径。

2 个答案:

答案 0 :(得分:3)

我认为这可以作为查询完成,您必须合并xmlagg xmlelementxmlforest

以下是一个例子:

select XMLELEMENT("product",(XMLForest( p.product_name as "productName",
                            p.product_number as "productNumber",
                  xmlagg(
  XMLELEMENT("obsoletedProduct", 
             XMLATTRIBUTES(po.label as "label"), 
             po.obsoleted_product_id)) as "productObsoletes")))
from products p 
join product_obsoletes po on p.product_number=po.id
group by p.product_name, p.product_number

here是小提琴

答案 1 :(得分:2)

如何使用XMLDOM(一个不同的内置包)来创建XML呢?

您可能需要编写更多代码,但如果您的逻辑非常复杂,那么无论如何您都必须这样做。


这是您可以使用的一些选项(包括XMLDOM)的快速摘要,并附带示例:

http://www.akadia.com/services/ora_gen_xml.html