2013-09-03 7 views
7

Ho un codice di xml:XML Oracle: Multiple estratto Nodo figlio

<begin> 
    <entry> 
     <lastname>gordon</lastname> 
     <NumberList> 
      <number>100</number> 
      <codelist> 
       <code>213</code> 
       <code>214</code> 
      <codelist> 
      <login> 
       <user>user1</user> 
       <user>user2</user> 
      </login> 
     <NumberList> 
     <address> 
      <addresslist>Jl. jalan pelan-pelan ke Bekasi, Indonesia</addresslist> 
     </address> 
    </entry> 
    <entry> 
     <lastname>mark</lastname> 
     <address> 
      <addresslist>Jl. jalan cepet-cepet ke Jakarta, Indonesia</addresslist> 
     </address> 
    </entry> 
</begin> 

il mio codice:

FOR r IN (SELECT VALUE(p) col_val, 
       EXTRACT(VALUE(P), '/entry/codelist') AS code, 
       EXTRACT(VALUE(P), '/entry/login') AS login 
      FROM TABLE(XMLSequence(Extract(x,'/begin/entry'))) p) 
LOOP 
    IF r.col_val.existsnode('/entry/lastname/text()') > 0 
    THEN 
     vc_lastname := r.col_val.extract('/sdnEntry/lastname/text()').getstringval(); 
    END IF; 

    IF r.col_val.existsnode('/entry/address/addresslist/text()') > 0 
    THEN 
    vc_address := r.col_val.extract('/sdnEntry/address/addresslist/text()').getstringval(); 
    END IF; 

    IF r.col_val.existsnode('/entry/codelist/id/code/text()') > 0 AND r.col_val.existsnode('/entry/login/user/text()') > 0 
    THEN 
     FOR R1 IN (SELECT EXTRACTVALUE(VALUE(T1), '/codelist/code/text()') AS code 
        FROM TABLE(XMLSEQUENCE(EXTRACT(R.code, '/codelist'))) T1) 
     LOOP 
     DBMS_OUTPUT.PUT_LINE(vc_uid||' - '||vc_firstName||' - '||R1.code||' - '||R2.address); 
     END LOOP; 

     FOR R2 IN (SELECT 
         EXTRACTVALUE(VALUE(T1), '/login/user/text()') AS user 
        FROM TABLE(XMLSEQUENCE(EXTRACT(R.address, 'login/'))) T1) 
     LOOP 
     DBMS_OUTPUT.PUT_LINE(vc_uid||' - '||vc_firstName||' - '||R2.user||' - '||R2.address); 
     END LOOP; 
    ELSE 
     DBMS_OUTPUT.PUT_LINE(vc_uid||' - '||vc_firstName); 
    END IF; 

Il mio problema: come ciclo nodi figlio in modo che i dati diventeranno in questo modo:

LastName | Number | code | user | address 
gordon | 100 | 213  | user1 |Jl. jalan pelan-pelan ke Bekasi, Indonesia 
gordon | 100 | 213  | user2 |Jl. jalan pelan-pelan ke Bekasi, Indonesia 
gordon | 100 | 214  | user1 |Jl. jalan pelan-pelan ke Bekasi, Indonesia 
gordon | 100 | 214  | user2 |Jl. jalan pelan-pelan ke Bekasi, Indonesia 
mark  | Null | null | null |Jl. jalan cepet-cepet ke Jakarta, Indonesia 

Qualsiasi aiuto sarebbe gradito.

+0

possibile duplicato di [Oracle XML: nodo Skip Not exist] (http://stackoverflow.com/questions/18583872/oracle-xml-skip-not-exist-node) – user272735

risposta

12

È possibile raggiungere il risultato desiderato con la funzione XMLTable():

select q.Lastname 
    , q.Numberid 
    , s.codeid 
    , w.LoginId 
    , q.address 
    from t1 t 
    left join xmltable('/begin/entry' 
         passing t.xml_col 
         columns LastName varchar2(21) path 'lastname', 
           NumberId number  path 'NumberList/number', 
           Address varchar2(201) path 'address/addresslist', 
           CodeList XmlType  Path 'NumberList/codelist/code', 
           Logins  XmlType  Path 'NumberList/login/user' 
        ) q 
    on (1=1) 
    left join xmltable('/code' 
         passing q.CodeList 
         columns CodeId number path '.') s 
    on (1=1) 
    left join xmltable('/user' 
         passing q.Logins 
         columns LoginId varchar2(11) path '.') w 
    on (1=1) 

Risultato: SQLFiddle Demo

Lastname Numberid Codeid Loginid Address 
--------------------------------------------------------------------------- 
gordon 100  213 user1 Jl. jalan pelan-pelan ke Bekasi, Indonesia 
gordon 100  213 user2 Jl. jalan pelan-pelan ke Bekasi, Indonesia 
gordon 100  214 user1 Jl. jalan pelan-pelan ke Bekasi, Indonesia 
gordon 100  214 user2 Jl. jalan pelan-pelan ke Bekasi, Indonesia 
mark  null  null null Jl. jalan cepet-cepet ke Jakarta, Indonesia 

Find out more su XMLTable() funzione.

Nota: Lavorare con Oracle rilascia prima 11.2.0.2, si possono incontrare ORA-1780 error (bug 8.545.377) su alcuni tipi di query XML quando cursor_sharing parametro è impostato su FORCE o SIMILAR (deprecato a partire da 11,2). L'impostazione del parametro cursor_sharing su EXACT (valore predefinito) risolverà il problema.

+0

ottimo !! .. utile per me. – ajmalmhd04

+1

perché sta sollevando l'errore 'ORA-01780: string letteral required' se non ho impostato' alter session set cursor_sharing = exact; ' ?? Sto usando 11g – ajmalmhd04

+1

ok grazie per le informazioni !! spero che tu intenda la condivisione invece di tosare – ajmalmhd04