0

SQL クエリ (Oracle 11g R2) を使用して、XML ファイル (BLOB 形式で保存) から入力されたテーブルを生成する必要があります。テーブルには、生徒ごとに 1 つの行が含まれている必要があります。

次の構文を使用しようとすると:

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

ただし、使用している構文は、ベース テーブルにその行が 1 つある場合にのみ有効です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). 必要に応じて文字セットを変更します。

于 2013-04-02T16:09:17.323 に答える