我使用的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 转换为表,请参阅以下内容:
从 XML 到 Oracle PL/SQL 环境中的路径列表 https://stackoverflow.com/questions/18146788/from-xml-to-list-of-paths-in-oracle-pl-sql-environment
我收到的答案很好,它适用于不太大的 XML。
但是,如果我有一个名为 MY_TABLE_ONE 的表,其中包含一个名为 MY_FIELD 的字段,该字段是一个内容非常大(例如 500 KB)的 CLOB,则以下语句不会在合理的时间内退出:
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'
);
是否有任何替代方法可以以更有效的方式转换存储在 Oracle 表中的 CLOB 列中的 XML,其中包含路径和相应值的列表?
上面的说法是对的,但是需要太多时间才能最终确定。
非常感谢您考虑我的请求。
EDIT:
我尝试过这个迭代解决方案,但没有成功:-(
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;