我在将非常大的XML文件加载到Oracle DB(80MB)时遇到问题。 XML文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<names>
<catalog>
<row>
<col name="NAME">John</col>
<col name="SURNAME">Smith</col>
<col name="AGE">24</col>
</row>
<row>
<col name="NAME">Matt</col>
<col name="SURNAME">Lick</col>
<col name="AGE">14</col>
</row>
</catalog>
</names>
我试图使其工作的代码如下所示:
CREATE directory TEST_DIR AS 'c:\Test';
INSERT INTO NAMES(NAME,SURNAME,AGE)
WITH t AS (SELECT xmltype(bfilename('TEST_DIR','NAMES.xml'), nls_charset_id('UTF8')) xmlcol FROM dual)
SELECT extractValue(value(x),'/row/col[@name="NAME"]') NAME
,extractValue(value(x),'/row/col[@name="SURNAME"]') SURNAME
,extractValue(value(x),'/row/col[@name="AGE"]') AGE
FROM t,TABLE(XMLSequence(extract(t.xmlcol,'/names/catalog/row'))) x;
我得到的是无限循环(我等待4小时请求结束。)当我尝试使用像40MB这样的小文件时它起作用 - 我得到的信息是在253s中插入了160,000条记录。 是否有任何参数或东西可以使这个导入也适用于更大的文件?我做错了什么?
欢呼声
答案 0 :(得分:0)
当您使用extractValue
或xmltype
等函数时,在DOM(文档对象模型)方法上解析XML。一旦我读到关于因子10-20的内容,这就会在内存中产生很大的开销!一般来说,使用DOM解析器解析XML文档并不聪明,如果它们大于“两位MB的上限”。
对于大型文档,您必须使用基于流的解析器,通常是SAX解析器。在大多数情况下,编码更多,但是文档的结构非常简单,所以应该没问题。
在我的应用程序中,我必须将最多1 GB的XML文件加载到我的Oracle DB中,我使用XML::Twig在Perl中编写了解析器,它运行良好。
答案 1 :(得分:0)
存储为安全文件二进制文件xml,以便您获得它提供的优化。
CREATE TABLE xxx ( xml_file XMLTYPE ) XMLTYPE xml_file STORE as securefile binary xml;
INSERT INTO xxx ( xml_file )
( SELECT XMLTYPE(bfinename(<directory object>,<file name>, nls_charset_id(<character set>)) from dual );
这里我建议改变&lt; col name =&#34; ???&#34;&gt;到&lt; ???&gt;&lt; / ???&gt;在xml中让你的生活更轻松。
SELECT name, surname, age
FROM XMLTABLE('/names/catalog/row' passing (SELECT xml_file FROM xxx)
COLUMNS name VARCHAR2(4000),
surname VARCHAR2(4000),
age NUMBER);