【问题标题】:XMLTABLE, XQUERY - expected singleton sequenceXMLTABLE、XQUERY - 预期的单例序列
【发布时间】:2019-04-17 16:42:58
【问题描述】:

XML:

<import>
    <persons>
        <person>
            <pm>57924160</pm>
            <date_from>2018-05-01</date_from>
            <info>
                <set>
                    <indflag>0</indflag>
                </set>
                <items>
                    <item>
                        <symbol>a</symbol>
                        <date>2018-05-02</date>
                        <cost>190</cost>
                    </item>
                    <item>
                        <symbol>b</symbol>
                        <date>2018-05-02</date>
                        <cost>130</cost>
                    </item>
                </items>
            </info>
        </person>
    </persons>
    <persons>
        <person>
            <pm>57924160</pm>
            <date_from>2018-05-01</date_from>
            <info>
                <set>
                    <indflag>0</indflag>
                </set>
                <items>
                    <item>
                        <symbol>a</symbol>
                        <date>2018-05-02</date>
                        <cost>190</cost>
                    </item>
                    <item>
                        <symbol>b</symbol>
                        <date>2018-05-02</date>
                        <cost>130</cost>
                    </item>
                </items>
            </info>
        </person>
    </persons>
</import>

我通过以下方式循环读取此 xml:

 SELECT xt.*
   FROM  XMLTABLE(
         '//import/persons/person'
         PASSING xmltype('above_xml')
         COLUMNS 
           pm        VARCHAR2(4)  PATH 'pm',
           indflag   VARCHAR2(10) PATH 'info/set/indflag'
         ) xt;

但如果我添加另一列

item      varchar2(10) PATH 'info/items/item/symbol'

它给了我 ORA,因为 xmltable 期望每人 1 个值,并且每个人有两个项目。

当然,我可以在 pl/sql 中处理它,例如获取完整的人员节点、选择所有项目等,但我想知道这是否可以在单个查询中完成,以获得如下输出:

PM    INDFLAG  item
5792    0        a
5792    0        b

【问题讨论】:

  • 每个人有多个项目/符号,所以您现在不希望结果集中有四行吗?

标签: sql xml oracle xmltable


【解决方案1】:

您可以使用两个级别的 XMLTable:

select x1.pm, x1.indflag, x2.item
  from  xmltable(
         '//import/persons/person'
         passing xmltype('above_xml')
         columns 
           pm        varchar2(4)  path 'pm',
           indflag   varchar2(10) path 'info/set/indflag',
           items     xmltype      path 'info/items'
         ) x1
  cross join  xmltable(
         '/items/item'
         passing x1.items
         columns 
           item      varchar2(10) PATH 'symbol'
         ) x2;

PM   INDFLAG    ITEM      
---- ---------- ----------
5792 0          a         
5792 0          b         
5792 0          a         
5792 0          b         

或者不太灵活,但这里只有一个子集合,从项目级别开始,然后为更高级别的节点数据备份:

select xt.pm, xt.indflag, xt.item
  from  xmltable(
         '//import/persons/person/info/items/item'
         passing xmltype('above_xml')
         columns 
           pm        varchar2(4)  path './../../../pm',
           indflag   varchar2(10) path './../../set/indflag',
           item      varchar2(10) PATH 'symbol'
         ) xt;

PM   INDFLAG    ITEM      
---- ---------- ----------
5792 0          a         
5792 0          b         
5792 0          a         
5792 0          b         

(第二种方法似乎在11.2.0.2 中不起作用,这一定是一个错误;它在 11.2.0.4 以及包括18c 在内的更高版本中起作用。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-04
    • 2017-07-12
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    相关资源
    最近更新 更多