Extract xml data using oracle query

2019-02-20 15:12发布

问题:

Oracle version 11g

HI , When trying to read the XML in a LOOP the query is giving an error but if, I change this to a non existing path then the query is running fine . However the @Name is not fetching is the expected . What should I correct here to make it give the desired output given below:

sqlfiddle link

Non exsisting path described above, removed the E from the name : for $i in AuxiliaryObject/Row return <C>{$i}<R>{AuxiliaryObject/@NAM}

code :

    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')

Output : Desired :

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

Output coming is in the sqlfiddle link.

The above Queation is a link to this : Extract data from a XML and load it into a table

When I run the query on Toad : Output is :

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:

I would extract the data in stages:

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;

The XMLTable xobjects contains each of the AuxiliaryObject instances within the AuxiliaryType, from your original XML text. It has the attributes name and id, plus a sub-XMLType containing the nested rows. The second XMLTable, xrows, expands that so the elements can be extracted. The joins and passing of the XML types creates the hierarchy that gives the output you want:

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                           

This works in SQL Developer against an 11.2.0.3 database, and in SQL Fiddle.

An earlier CTE-based version of this answer also worked in SQL Developer but SQL Fiddle got an ORA-600 error; that along with the issue you had in the question suggests maybe SQL Fiddle is on an unpatched, or at least differently patched, version of 11gR2 which has bugs in the XML handling.