Oracle:加载一个大的xml文件?

时间:2009-06-15 19:54:14

标签: sql xml oracle

现在我有一大堆我感兴趣的XML数据:

http://blog.stackoverflow.com/2009/06/stack-overflow-creative-commons-data-dump

我想把它加载到Oracle中来玩。

如何直接将大型XML文件直接加载到Oracle?服务器端解决方案(可以在服务器上打开数据文件)和客户端解决方案受到欢迎。

这是一个具体例子的badges.xml。

<?xml version="1.0" encoding="UTF-8" ?>
  <badges>
  <row UserId="3718" Name="Teacher" Date="2008-09-15T08:55:03.923"/>
  <row UserId="994" Name="Teacher" Date="2008-09-15T08:55:03.957"/>
  ...

3 个答案:

答案 0 :(得分:12)

您可以通过SQL访问服务器上的XML文件。使用/tmp/tmp.xml中的数据,首先要声明目录:

SQL> create directory d as '/tmp';

Directory created

然后,您可以直接查询XML文件:

SQL> SELECT XMLTYPE(bfilename('D', 'tmp.xml'), nls_charset_id('UTF8')) xml_data
  2    FROM dual;

XML_DATA
--------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<badges>
  [...]

要访问文件中的字段,您可以使用another SO中描述的方法,例如:

SQL> SELECT UserId, Name, to_timestamp(dt, 'YYYY-MM-DD"T"HH24:MI:SS.FF3') dt
  2    FROM (SELECT XMLTYPE(bfilename('D', 'tmp.xml'), 
                            nls_charset_id('UTF8')) xml_data
  3            FROM dual),
  4         XMLTable('for $i in /badges/row
  5                              return $i'
  6                  passing xml_data
  7                  columns UserId NUMBER path '@UserId',
  8                          Name VARCHAR2(50) path '@Name',
  9                          dt VARCHAR2(25) path '@Date');

    USERID NAME       DT                         
---------- ---------- ---------------------------
      3718 Teacher    2008-09-15 08:55:03.923    
       994 Teacher    2008-09-15 08:55:03.957    

答案 1 :(得分:3)

好像你在谈论2个问题 - 首先,将XML文档提供给Oracle可以看到的地方。然后可能使标准关系工具可以应用于数据。

对于第一个,您或您的DBA可以创建一个包含BLOB,CLOB或BFILE列的表并加载数据。如果可以访问数据库所在的服务器,则可以在数据库中定义指向操作系统目录的DIRECTORY对象。然后把你的文件放在那里。然后将其设置为BFILE或将其读入。(数据库中的CLOB和BLOB存储; BFILE存储指向操作系统端的文件)。

或者,使用一些工具可以直接将CLOB写入数据库。无论如何,这使您可以在数据库中看到XML实例文档。

现在您可以看到实例文档了。第1步已完成。

根据版本的不同,Oracle有一些很好的工具可以将XML分解为关系表。

它可以很具说服力。虽然这超出了我实际完成的范围(我有一个项目,我将在今年秋天尝试它),理论上你可以将XML Schema加载到数据库中,并使用关系表和XML之间的人行横道来注释它。然后把你的CLOB或BFILE转换成带有定义模式的XMLTYPE列,你就完成了 - 碎片自动发生,数据全部存在,它都是关系的,它都可用于没有XQUERY或XML的标准SQL扩展。

当然,如果您更愿意使用XQUERY,那么只需使用CLOB或BFILE,将其转换为XMLTYPE即可。

答案 2 :(得分:0)

我会做一个简单的事情:

grep '<row' file.xml |\
gawk -F '"' '{printf("insert into badges(userid,name,date) values (\"%s\",\"%s\",\"%s\");\n",$2,$4,$6); } > request.sql

或者您可以使用SAX解析器创建Java程序。每次处理程序找到新的元素“行”时,您将获得属性并在数据库中插入新记录。