XML Oracle:多子节点提取

2023-11-02数据库问题
0

本文介绍了XML Oracle:多子节点提取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个 xml 代码:

I have an xml code :

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

我的问题:如何循环子节点使数据变成这样:

My problem : How to loop child nodes so the data will become like this :

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() 函数来达到预期的效果:

You can achieve desired result by using XMLTable() function:

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 版本,当 cursor_sharing 参数设置为 FORCESIMILAR(从 11.2 开始弃用).将cursor_sharing参数设置为EXACT(默认值),即可解决问题.

Note: Working with Oracle releases prior to 11.2.0.2, you can encounter ORA-1780 error(bug 8545377) on certain types of XML queries when cursor_sharing parameter is set to FORCE or SIMILAR(deprecated starting from 11.2). Setting cursor_sharing parameter to EXACT(default value), will solve the problem.

这篇关于XML Oracle:多子节点提取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

Mysql目录里的ibtmp1文件过大造成磁盘占满的解决办法
ibtmp1是非压缩的innodb临时表的独立表空间,通过innodb_temp_data_file_path参数指定文件的路径,文件名和大小,默认配置为ibtmp1:12M:autoextend,也就是说在文件系统磁盘足够的情况下,这个文件大小是可以无限增长的。 为了避免ibtmp1文件无止境的暴涨导致...
2025-01-02 数据库问题
151

按天分组的 SQL 查询
SQL query to group by day(按天分组的 SQL 查询)...
2024-04-16 数据库问题
77

SQL 子句“GROUP BY 1"是什么意思?意思是?
What does SQL clause quot;GROUP BY 1quot; mean?(SQL 子句“GROUP BY 1是什么意思?意思是?)...
2024-04-16 数据库问题
62

MySQL groupwise MAX() 返回意外结果
MySQL groupwise MAX() returns unexpected results(MySQL groupwise MAX() 返回意外结果)...
2024-04-16 数据库问题
13

MySQL SELECT 按组最频繁
MySQL SELECT most frequent by group(MySQL SELECT 按组最频繁)...
2024-04-16 数据库问题
16

在 Group By 查询中包含缺失的月份
Include missing months in Group By query(在 Group By 查询中包含缺失的月份)...
2024-04-16 数据库问题
12