使用oracle查询提取xml数据

时间:2014-01-03 08:51:55

标签: sql xml oracle plsql xml-parsing

Oracle 11g版本

嗨, 当尝试在LOOP中读取XML时,查询会给出错误,但是如果我将其更改为非现有路径,则查询运行正常。但是,@Name未获取是预期的。我应该在这里纠正什么,使其得到下面给出的所需输出:

sqlfiddle link

上述非现有路径,从名称中移除了E:for $i in AuxiliaryObject/Row return <C>{$i}<R>{AuxiliaryObject/@NAM}

代码:

    SELECT *
FROM XMLTABLE (
               '<C> {for $i in AuxiliaryObject/Row return <C>{$i}<R>{AuxiliaryObject/@NAM}</R></C>}</C>/C'
               PASSING xmltype(
               '<AuxiliaryType>
                 <AuxiliaryObject id="1" NAME="Provider_P107">
                         <Row>
                              <Index_id>1</Index_id>
                              <Provider_ID_description>GNRCN</Provider_ID_description>
                              <Provider_ID>GNRCN</Provider_ID>
                         </Row>

                          <Row>
                              <Index_id>2</Index_id>
                              <Provider_ID_description>EGUT12</Provider_ID_description>
                              <Provider_ID>EGUT12 </Provider_ID>
                         </Row>
                 </AuxiliaryObject>
                 <AuxiliaryObject id="2" NAME="Provider_P108">
                         <Row>
                              <Index_id>1</Index_id>
                              <Provider_ID_description>GNRCN</Provider_ID_description>
                              <Provider_ID>GNRCN</Provider_ID>
                         </Row>

                          <Row>
                              <Index_id>2</Index_id>
                              <Provider_ID_description>EGUT</Provider_ID_description>
                              <Provider_ID>EGUT </Provider_ID>
                         </Row>
                 </AuxiliaryObject>

                </AuxiliaryType>'
               ).EXTRACT ('AuxiliaryType/*') 
               COLUMNS 
                        Name varchar (30) Path 'R/@NAME',
                        Index_Id VARCHAR2 (10) PATH 'Row/Index_id', 
                       Provider_id_description   VARCHAR2 (30) PATH 'Row/Provider_ID_description',
                       provider_id  VARCHAR2 (30) PATH 'Row/Provider_ID')

输出:所需:

ID,  Provider_Name,  Index, Provider_ID_description, Provider_ID
 1  Provider_P107     1     GNRCN                   GNRCN
 1  Provider_P107     2     INDF1                   INDF1
 2  Provider_P108     2     EGUT12                  EGUT12
 2  Provider_P108     1     EGUT                    EGUT

输出来自sqlfiddle链接。

上面的Queation是这个的链接: Extract data from a XML and load it into a table

当我在Toad上运行查询时:输出为:

NAME    INDEX_ID    PROVIDER_ID_DESCRIPTION PROVIDER_ID
Provider_P107Provider_P108  1   GNRCN   GNRCN
Provider_P107Provider_P108  2   EGUT12  EGUT12 
Provider_P107Provider_P108  1   GNRCN   GNRCN
Provider_P107Provider_P108  2   EGUT    EGUT 

1 个答案:

答案 0 :(得分:2)

我会分阶段提取数据:

SELECT xobjects.id, xobjects.name, xrows.index_id,
  xrows.provider_id_description, xrows.provider_id
FROM XMLTABLE(
    '/AuxiliaryType/AuxiliaryObject'
    PASSING xmltype(
               '<AuxiliaryType>
                 <AuxiliaryObject id="1" NAME="Provider_P107">
                         <Row>
                              <Index_id>1</Index_id>
                              <Provider_ID_description>GNRCN</Provider_ID_description>
                              <Provider_ID>GNRCN</Provider_ID>
                         </Row>

                          <Row>
                              <Index_id>2</Index_id>
                              <Provider_ID_description>EGUT12</Provider_ID_description>
                              <Provider_ID>EGUT12 </Provider_ID>
                         </Row>
                 </AuxiliaryObject>
                 <AuxiliaryObject id="2" NAME="Provider_P108">
                         <Row>
                              <Index_id>1</Index_id>
                              <Provider_ID_description>GNRCN</Provider_ID_description>
                              <Provider_ID>GNRCN</Provider_ID>
                         </Row>

                          <Row>
                              <Index_id>2</Index_id>
                              <Provider_ID_description>EGUT</Provider_ID_description>
                              <Provider_ID>EGUT </Provider_ID>
                         </Row>
                 </AuxiliaryObject>

                </AuxiliaryType>'
    )
    COLUMNS 
    name VARCHAR2(30) PATH '@NAME',
    id VARCHAR2(10) PATH '@id',
    xrows XMLTYPE PATH 'Row') xobjects,
  XMLTABLE(
    '/Row'
    PASSING xobjects.xrows
    COLUMNS
    index_id VARCHAR2(10) PATH 'Index_id', 
    provider_id_description VARCHAR2(30) PATH 'Provider_ID_description',
    provider_id  VARCHAR2(30) PATH 'Provider_ID') xrows;

XMLTable xobjects包含原始XML文本中AuxiliaryObject中的每个AuxiliaryType个实例。它具有属性nameid,以及包含嵌套行的子XMLType。第二个XMLTable xrows扩展了它,因此可以提取元素。 XML类型的连接和传递创建了提供所需输出的层次结构:

ID         NAME                           INDEX_ID   PROVIDER_ID_DESCRIPTION        PROVIDER_ID                  
---------- ------------------------------ ---------- ------------------------------ ------------------------------
1          Provider_P107                  1          GNRCN                          GNRCN                          
1          Provider_P107                  2          EGUT12                         EGUT12                         
2          Provider_P108                  1          GNRCN                          GNRCN                          
2          Provider_P108                  2          EGUT                           EGUT                           

这适用于SQL Developer对11.2.0.3数据库和SQL Fiddle

这个答案的早期基于CTE的版本在SQL Developer中也有效但SQL Fiddle出现了ORA-600错误;这个问题以及你在问题中提出的问题表明,SQL Fiddle可能是一个未修补的,或者至少是不同版本的11gR2,它在XML处理中存在缺陷。