如何从以BLOB格式存储的XML文件生成表?

时间:2013-04-02 15:47:34

标签: sql oracle oracle11gr2

我需要使用SQL查询(Oracle 11g R2)生成从XML文件(以BLOB格式存储)填充的表。该表应包含每个学生一行。

当我尝试使用以下语法时:

select x.*
from XMLTABLE('/XML/highschool/class/student' passing (SELECT XML_CONTENT
   FROM T_FILES
   WHERE ID_FILE = 1)
   columns seq for ordinality,
   STUDENT_NAME Varchar2(500) PATH 'cd[@name=''STUDENT_NAME'']@data'
)
as x;

我收到错误

19109. 00000 -  "RETURNING keyword expected"
*Cause:    The keyword RETURNING was missing.
*Action:   Specify the RETURNING keyword.

我尝试使用dbms_xmlgen.getxmltype和其他一些解决方案但没有成功。

1 个答案:

答案 0 :(得分:1)

您的XPATH已损坏。

使用:

PATH 'cd[@name="STUDENT_NAME"]/@data'

例如:

SQL> create table T_FILES
  2  (XML_CONTENT xmltype, ID_FILE number);

Table created.

SQL> insert into t_files values (
  2  xmltype('<XML>
  3    <highschool>
  4      <class>
  5        <user>
  6          <cd name="STUDENT_NAME" data="foo"/>
  7        </user>
  8        <user>
  9          <cd name="STUDENT_NAME" data="foo2"/>
 10        </user>
 11      </class>
 12    </highschool>
 13  </XML>'), 1);

1 row created.

SQL> commit;

Commit complete.

SQL> select /*+ cursor_sharing_exact */ a.*
 2  from XMLTABLE('/XML/highschool/class/user' PASSING  (SELECT XML_CONTENT
 3     FROM T_FILES
 4     WHERE ID_FILE = 1)
 5               columns
 6               seq for ordinality,
 7               STUDENT_NAME Varchar2(500) PATH 'cd[@name="STUDENT_NAME"]/@data'
 8       )  a;

      SEQ STUDENT_NAME
--------- --------------------
        1 foo
        2 foo2

VS

SQL>  select /*+ cursor_sharing_exact */ a.*
  2  from XMLTABLE('/XML/highschool/class/user' PASSING  (SELECT XML_CONTENT
  3     FROM T_FILES
  4     WHERE ID_FILE = 1)
  5               columns
  6               seq for ordinality,
  7               STUDENT_NAME Varchar2(500) PATH 'cd[@name=''STUDENT_NAME'']@data'
  8       )  a;
from XMLTABLE('/XML/highschool/class/user' PASSING  (SELECT XML_CONTENT

虽然您使用的语法仅在基表中有ID_FILE的一行时才有效。如果不是,则必须将表格放在xmltable定义之外,如:

select /*+ cursor_sharing_exact */ a.*
from T_FILES t,
     XMLTABLE('/XML/highschool/class/user' PASSING  t.XML_CONTENT
             columns
             seq for ordinality,
             STUDENT_NAME Varchar2(500) PATH 'cd[@name="STUDENT_NAME"]/@data'
     )  a
WHERE t.ID_FILE = 1;

如果你把XML放在BLOB中而不是从blob存储为XMLTYPE,那么用select转换为:

select /*+ cursor_sharing_exact */ a.*
from XMLTABLE('/XML/highschool/class/user' PASSING  
             (SELECT xmltype.createxml(XML_CONTENT, NLS_CHARSET_ID('UTF8'), null)
                FROM T_FILES
               WHERE ID_FILE = 1)
             columns
             STUDENT_NAME Varchar2(500) PATH 'cd[@name="STUDENT_NAME"]/@data'
     )  a;

即。 xmltype.createxml(XML_CONTENT, NLS_CHARSET_ID('UTF8'), null)。根据需要更改字符集。