从xmltype获取数据时出错

时间:2014-02-05 07:31:05

标签: oracle plsql oracle11g syntax-error xmltype

我是XMLTYPE数据处理的新手,所以它可能只是一个非常简单的查询,我无法弄清楚。请让我知道我错在哪里。

使用以下代码尝试时出错。

ORA-06550: line 28, column 54:
PL/SQL: ORA-00933: SQL command not properly ended
ORA-06550: line 22, column 3:
PL/SQL: SQL Statement ignored
ORA-06550: line 29, column 4:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

这是我的代码。

DECLARE
     x XMLTYPE :=XMLTYPE('<?xml version="1.0" ?> 
                         <person>   
                         <row>       
                         <name>Tom</name>       
                         <Address>           
                         <State>California</State>           
                         <City>Los angeles</City>       
                         </Address>   
                         </row>   
                         <row>       
                         <name>Jim</name>       
                         <Address>           
                         <State>California</State>           
                         <City>Los angeles</City>       
                         </Address>   
                         </row>                         
                         </person>');
     l_city VARCHAR2(20);
     l_state VARCHAR2(20);
     l_name VARCHAR2(20);
BEGIN

     SELECT EXTRACT(VALUE(p),'//name/text()')          AS "Name",
         extract(value(p),'/Address//State/text()') AS "State",
         extract(value(p),'/Address//City/text()')  AS "City"
     FROM   dual,
         TABLE(XMLSEQUENCE(EXTRACT(x,'//person/row/'))) p;
END;

3 个答案:

答案 0 :(得分:1)

您无需从DUAL表中进行选择,而是可以直接从XMLSEQUENCE函数进行查询。您可以尝试使用以下查询。

 SELECT EXTRACTVALUE(VALUE(p),'//name') AS "Name",
        EXTRACTVALUE(VALUE(p),'//Address/State') AS "State",
        EXTRACTVALUE(VALUE(p),'//Address/City')  AS "City"
 INTO   ..
 FROM   TABLE(XMLSEQUENCE(EXTRACT(x,'//person/row')))p;

答案 1 :(得分:1)

您可以尝试以下。请注意,在您的情况下,XMLSEQUENCE为您提供顶级节点的VARRAY,因此仅INTO可能就不够了。

DECLARE
   TYPE l_obj IS RECORD
   (
      name    VARCHAR2 (200),
      state   VARCHAR2 (200),
      city    VARCHAR2 (200)
   );

   TYPE l_list_table IS TABLE OF l_obj;

   l_list   l_list_table;
   x        XMLTYPE := XMLTYPE ('<?xml version="1.0" ?> 
<person>   
<row>       
<name>Tom</name>       
<Address>           
<State>California</State>           
<City>Los angeles</City>       
</Address>   
</row>   
<row>       
<name>Jim</name>       
<Address>           
<State>California</State>           
<City>Los angeles</City>       
</Address>   
</row>
</person>');
BEGIN
   SELECT EXTRACTVALUE (VALUE (p), '//name/text()'),
          EXTRACTVALUE (VALUE (p), '//Address/State/text()'),
          EXTRACTVALUE (VALUE (p), '//Address/City/text()')
     BULK COLLECT INTO l_list --please use LIMIT clause
     FROM TABLE (XMLSEQUENCE (EXTRACT (x, '/person/row/*'))) p;

   FOR idx IN l_list.FIRST .. l_list.LAST
   LOOP
      DBMS_OUTPUT.put_line (l_list(idx).name ||', '|| l_list (idx).state || ', ' || l_list (idx).city);
   END LOOP;
END;

答案 2 :(得分:0)

你可以试试这个:

WITH xx AS (SELECT xmltype('<?xml version="1.0" ?> 
<person>   
<row>       
<name>Tom</name>       
<Address>           
<State>California</State>           
<City>Los angeles</City>       
</Address>   
</row>   
<row>       
<name>Jim</name>       
<Address>           
<State>California</State>           
<City>Los angeles</City>       
</Address>   
</row>
</person>') col1 FROM DUAL)
SELECT EXTRACT(VALUE(p), '//name/text()') AS "Name",
       EXTRACT(VALUE(p), '//Address//State/text()') AS "State",
       EXTRACT(VALUE(p), '//Address//City/text()') AS "City"
  FROM TABLE(XMLSEQUENCE(EXTRACT((SELECT t1.col1
                                    FROM xx t1),
                                 '//person/row'))) p;

或使用COLMUN_VALUE伪colmun:

WITH xx AS (SELECT xmltype('<?xml version="1.0" ?> 
<person>   
<row>       
<name>Tom</name>       
<Address>           
<State>California</State>           
<City>Los angeles</City>       
</Address>   
</row>   
<row>       
<name>Jim</name>       
<Address>           
<State>California</State>           
<City>Los angeles</City>       
</Address>   
</row>
</person>') col1 FROM DUAL)
SELECT EXTRACT(column_value, '//name/text()') AS "Name",
       EXTRACT(column_value, '//Address//State/text()') AS "State",
       EXTRACT(column_value, '//Address//City/text()') AS "City"
  FROM TABLE(XMLSEQUENCE(EXTRACT((SELECT t1.col1
                                    FROM xx t1),
                                 '//person/row')));

我希望它有所帮助。 Cyryl