我有一个xml代码:
<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>
我的代码:
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;
我的问题:如何循环子节点,以便数据将变成这样:
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
任何帮助将不胜感激。
您可以使用以下XMLTable()功能获得所需的结果:
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)
结果: SQLFiddle演示
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
了解有关XMLTable()功能的更多信息。
注意 :使用11.2.0.2之前的Oracle版本ORA-1780 error时,当cursor_sharing参数设置为FORCE或SIMILAR(从11.2开始不推荐使用)时,您会遇到某些类型的XML查询的(错误8545377 )。将cursor_sharing参数设置为EXACT(默认值)将解决此问题。
ORA-1780 error
cursor_sharing
FORCE
SIMILAR
EXACT