0

我需要使用 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 和其他一些解决方案但没有成功。

4

1 回答 1

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

对比

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 /*+ 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;

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

于 2013-04-02T16:09:17.323 回答