将 100,000 条记录从 PL/SQL 程序输出到 XML 文件的最佳方法

Posted

技术标签:

【中文标题】将 100,000 条记录从 PL/SQL 程序输出到 XML 文件的最佳方法【英文标题】:Best way to output 100,000 records from PL/SQL program into XML file 【发布时间】:2016-03-17 10:03:56 【问题描述】:

我是 XML 新手,但我被分配了一项任务,将包含 100,000 条记录的测试集输出到 XML 文件,这将是一个更大的文件。在每条记录中都有需要输出到文件的子数据子集(参见下面的代码结构)。

我正在尝试找到此 dbms_xmldom 的最佳解决方案,但在论坛上查看这是一个过时的工具,但我知道有 XMLElement,但我认为这仅适用于 SQL 而不是 PL/SQL。

除了 dbms_xmldom 之外,还有其他在 PL/SQL 中有效的东西同样好,或者我应该坚持我正在做的事情。该工具必须将每条记录输出到一个输出文件。

数据库的当前版本是11g release 1。

任何建议都会非常感谢。

  BEGIN

  For r_prod_rec IN c_prod_rec
  LOOP
    output process master record to XML file

    For r_prod_child1_rec IN c_prod_child1_rec(r_prod_rec.id)
    LOOP
         output process child record from table1 to XML file
    END LOOP

    For r_prod_child2_rec IN c_prod_child2_rec(r_prod_rec.id)
    LOOP
         output process child record table2 to XML file
    END LOOP

  END LOOP

  END

【问题讨论】:

你为什么不把 SQL 作为解决方案? 我同意 MT0 你不能在 sql 中生成并导出吗? docs.oracle.com/cd/E11882_01/appdev.112/e23094/… xmlelement 和其他 XML 函数(如 xmlforest)在 PL/SQL 中也能很好地工作。为什么你认为它们不起作用? 【参考方案1】:

Oracle 设置

CREATE TABLE parents ( ID, Attr1, Attr2 ) AS
SELECT LEVEL, 'A.' || LEVEL, 'B.' || LEVEL
FROM   DUAL
CONNECT BY LEVEL <= 5;

CREATE TABLE children ( ID, Attr1, Parent_ID ) AS
SELECT LEVEL, 'C.' || LEVEL, CASE WHEN LEVEL <= 3 THEN 1
                                  WHEN LEVEL <= 6 THEN 2
                                  WHEN LEVEL <= 8 THEN 4
                                                  ELSE 5
                             END FROM DUAL
CONNECT BY LEVEL <= 9;

查询

SELECT XMLELEMENT(
         "Root",
         XMLAGG(
           XMLELEMENT(
             "Parent",
             XMLATTRIBUTES(
               p.id,
               p.attr1 AS "A",
               p.attr2 AS "B"
             ),
             c.child_xml
           )
         )
       ).getClobVal() AS xml
FROM   parents p
       LEFT OUTER JOIN (
         SELECT parent_id,
                XMLAGG(
                  XMLELEMENT(
                    "Child",
                    XMLATTRIBUTES( id ),
                    attr1
                  )
                ) AS child_xml
         FROM   children
         GROUP BY parent_id
       ) c
       ON ( p.id = c.parent_id );

输出

XML
-------------------------------------------------------------------------------------------
<Root><Parent ID="1" A="A.1" B="B.1"><Child ID="1">C.1</Child><Child ID="2">C.2</Child>
<Child ID="3">C.3</Child></Parent><Parent ID="2" A="A.2" B="B.2"><Child ID="4">C.4</Child>
<Child ID="5">C.5</Child><Child ID="6">C.6</Child></Parent><Parent ID="3" A="A.3" B="B.3">
</Parent><Parent ID="4" A="A.4" B="B.4"><Child ID="7">C.7</Child><Child ID="8">C.8</Child>
</Parent><Parent ID="5" A="A.5" B="B.5"><Child ID="9">C.9</Child></Parent></Root>

如果您想在 PL/SQL 中使用它,那么只需:

DECLARE
  p_xml CLOB;
BEGIN
  SELECT ...
  INTO   p_xml
  FROM   ...;

  -- Then use the xml value.
END;
/

【讨论】:

【参考方案2】:

Oracle 有包 DBMS_XMLGEN。您可以使用它将查询结果转换为 xmltype。在我的示例中,我还使用了“CURSOR Expressions”。

declare   
     v_xml xmltype;
begin    
     v_xml := DBMS_XMLGEN.GETXMLTYPE ('select cursor(select x.COLUMN_NAME,x.DATA_TYPE from user_tab_columns x where x.table_name = y.table_name),y.table_name from user_tables y where rownum < 3');
    dbms_output.put_line(v_xml.getClobVal());
end;

【讨论】:

以上是关于将 100,000 条记录从 PL/SQL 程序输出到 XML 文件的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

在 Redshift 中获取超过 100,000 条记录 [关闭]

需要从 Core Data 中读取 10,000 条记录

用于更新超过 1 000 000 行的 Pl/Sql 脚本

Oracle Pl/sql 从多个查询中返回一个游标

在 C# 中将 100 000 条记录插入 MDB 文件的最快方法是啥

调用从 Hibernate 返回记录列表的 PL/SQL 函数