XMLTABLE到关系层次结构

时间:2014-05-21 16:40:10

标签: oracle xpath xquery xmltable

我有一个XML结构,其层次结构将存储在EAV架构中,其中一个表存储带有parent_id列的层次结构。级别可以包含多个元素,如本例中的

是否有更好的方法来处理层次结构,而不是像这样串联它?在这种情况下,我认为层次级别的数量有限,但这似乎不正确:

with x as (select xmltype('
 <data>  
   <row level="1a">
         <row level="1a2a">         
           <row level="1a2a3a"/> 
           <row level="1a2a3b"/> 
         </row>
         <row level="1a2b">         
           <row level="1a2b3a"/> 
           <row level="1a2b3b"/> 
         </row>
     </row>
     <row level="2a">
          <row level="2a1a">
               <row level="2a1a3a"/>
               <row level="2a1a3b"/>
        </row>
     </row>
     </data>') as xml from dual)
  select t1.l1, t2.l2, t3.l3
  from   x
        ,xmltable('/data/row'
                  passing x.xml
                  columns l1 varchar(20) path './@level'
                         , l2x xmltype  path './row'
                 ) t1
           ,xmltable('./row'
                  passing t1.l2x
                  columns l2 varchar2(20) path './@level'
                        , l3x xmltype  path './row'                           
                 ) t2
           ,xmltable('./row'
                  passing t2.l3x
                  columns l3 varchar2(20) path './@level'
                 ) t3                

1 个答案:

答案 0 :(得分:0)

可以使用更复杂的XQuery:

with x as (
  select xmltype('
    <data>  
      <row level="1a">
        <row level="1a2a">         
          <row level="1a2a3a"/> 
          <row level="1a2a3b"/> 
        </row>
        <row level="1a2b">         
          <row level="1a2b3a"/> 
          <row level="1a2b3b"/> 
        </row>
     </row>
     <row level="2a">
        <row level="2a1a">
           <row level="2a1a3a"/>
           <row level="2a1a3b"/>
        </row>
     </row>
   </data>'
  ) as xml from dual
)
select 
  h.level_id, 
  h.parent_id
from 
  x,
  xmltable(
    '               
      for $i in $doc//row  
      let $j := $i/..
      return <res>
               <lvl>{data($i/@level)}</lvl>
               <prnt>{data($j/@level)}</prnt>
             </res>
    '
    passing x.xml as "doc"
    columns 
      level_id  varchar2(100) path '//lvl',
      parent_id varchar2(100) path '//prnt'
  ) h