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 ответ

Это возможно с немного более сложным 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
Другие вопросы по тегам