2014-02-05 118 views
0

我是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; 
+0

你只是有一個語法錯誤。在PL/SQL中,你必須使用'SELECT INTO'。請參閱Oracle PL/SQL文檔。 – user272735

回答

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; 
+0

謝謝。請您好好解釋一下爲什麼我們在這種情況下使用「*」FROM TABLE(XMLSEQUENCE(EXTRACT(x,'/ person/row/*')))p; – user3274103

+0

對不起,不能「」。請詳細說明。如果您在談論XMLSEQUENCE,那麼這個Oracle文檔可能會幫助您[鏈接](http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions226.htm) –

+0

對不起,我的壞!我試圖說明你爲什麼在(XMLSEQUENCE(EXTRACT(x,'/ person/row/*')))p中使用「*」 另外請解釋你爲什麼要採取「人/行/」,是否因爲它包含所有的孩子節點?請解釋 – user3274103

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; 
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