【发布时间】:2015-01-01 09:36:28
【问题描述】:
我使用的 Oracle 版本是:
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for IBM/AIX RISC System/6000: Version 10.2.0.4.0 - Productio
NLSRTL Version 10.2.0.4.0 - Production
在上一个问题中,我问过如何将 clob 转换为表格,请参见:
From XML to list of paths in Oracle PL/SQL environment
我收到的答案很好,它适用于不太大的 XML。
但是,如果我有一个名为 MY_TABLE_ONE 的表,其中有一个名为 MY_FIELD 的字段,该字段是一个内容非常大的 CLOB(例如 500 KB),则以下语句不会在合理的时间内退出:
CREATE TABLE MY_TABLE_TWO
AS
WITH PARAMS AS (SELECT XMLTYPE (MY_FIELD) FROM MY_TABLE_ONE)
SELECT ELEMENT_PATH, ELEMENT_TEXT
FROM XMLTABLE (
'
for $i in $doc/descendant-or-self::*
return <element>
<element_path> {$i/string-join(ancestor-or-self::*/name(.), ''/'')} </element_path>
<element_content> {$i/text()}</element_content>
</element>
'
PASSING (SELECT * FROM PARAMS) AS "doc"
COLUMNS ELEMENT_PATH VARCHAR2 (4000) PATH '//element_path',
ELEMENT_TEXT VARCHAR2 (4000) PATH '//element_content'
);
是否有任何替代方法可以更高效地转换存储在 CLOB 列中的 XML,在 Oracle 表中包含路径列表和相应值?
上面的说法是对的,但需要太多时间来敲定。
非常感谢您考虑我的要求。
编辑:
我已经尝试过这个迭代解决方案,但没有成功:-(
BEGIN
DECLARE
CURSOR S_CUR
IS
WITH PARAMS AS (SELECT XMLTYPE (MY_FIELD) FROM MY_TABLE_ONE)
SELECT ELEMENT_PATH, ELEMENT_TEXT
FROM XMLTABLE (
'
for $i in $doc/descendant-or-self::*
return <element>
<element_path> {$i/string-join(ancestor-or-self::*/name(.), ''/'')} </element_path>
<element_content> {$i/text()}</element_content>
</element>
'
PASSING (SELECT * FROM PARAMS where rownum < 101) AS "doc"
COLUMNS ELEMENT_PATH VARCHAR2 (4000) PATH '//element_path',
ELEMENT_TEXT VARCHAR2 (4000) PATH '//element_content'
);
TYPE FETCH_ARRAY IS TABLE OF S_CUR%ROWTYPE;
S_ARRAY FETCH_ARRAY;
BEGIN
EXECUTE IMMEDIATE 'ALTER SESSION SET DB_FILE_MULTIBLOCK_READ_COUNT=256';
EXECUTE IMMEDIATE 'TRUNCATE TABLE GOOFY99 DROP STORAGE';
OPEN S_CUR;
LOOP
FETCH S_CUR
BULK COLLECT INTO S_ARRAY
LIMIT 500;
FORALL I IN 1 .. S_ARRAY.COUNT
INSERT /*+APPEND */
INTO GOOFY99
VALUES S_ARRAY (I);
COMMIT;
EXIT WHEN S_CUR%NOTFOUND;
END LOOP;
CLOSE S_CUR;
COMMIT;
END;
END;
【问题讨论】:
-
能否请您在某处发布有问题的大型 XML 文件? (我不想这么说,但我还不知道 XmlQuery 语法,所以我无法从你的选择中对你的 XML 结构进行逆向工程。)
-
XML 包含保留的数据和标签,所以我必须在发布到互联网之前对其进行修改......这不是那么直接!
-
明白。不着急。
-
我在 12.1.0.2 EE 上针对构造为
xmltype(cursor(select * from dba_objects))的 XML 数据进行了尝试(总共 46 MB 的 XML 数据存储在外联 CLOB 中)。您的第一个查询CREATE TABLE MY_TABLE_TWO AS ...在 11.5 秒内运行。我会在 11.2 XE 上尝试同样的方法。 -
11.2 XE,相同的 XML 结构(总共 6.5 MB 的 XML 数据),创建表运行时间为 90 秒。越来越接近你的问题,我猜。