使用 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 总是放置一个结束标记,所以除非您可以制定一个包含所有元素的选择语句,否则它不会起作用。其次,在本例中,我将覆盖先前的 XMLELEMENT 输出。我无法连接,因为 XMLELEMENT 已经关闭了标签。
此时我能想到的唯一解决方案是将我需要的各种 XMLElement 片段选择到不同的 VARCHARS 中,然后使用字符串操作函数找到插入各个片段的正确位置。丑陋的大写字母U。
还有其他解决方案吗?有没有办法阻止 XMELEMENT 关闭标签,以便您可以使用复杂的循环逻辑?或者另一个 Oracle 构造,它允许我实现构建此 XML 的目标,而无需使用单个 select 语句?
我最后的方法是从另一种语言(如 Java 或 Perl)生成 XML,我可以在其中简单地获取数据,然后在那里进行复杂的处理和 XML 生成。但是,我更喜欢只有一个 SQL 函数,它可以将正确的 XML 作为字符串返回,所以如果可以在 PL/SQL 中完成,那将是我的首选路线。