2014-09-03 3 views
4

У меня есть таблица вроде этого:XML оракул выберите запрос

Type Root Description  hierarchy_level 
Event 1  Jump   1 
Event 10  Dance   2 
Event 2  Cough   1 
Event 20  Sneeze   2 
Event 21  Spin   2 
Event 21  Run    3 
Event 21  Walk   4 

Я хочу, чтобы результат XML быть:

<Event 
    <child desc="Jump"> 
     <grandchild desc="Dance"/> 
    </child> 
    <child desc="Cough"> 
     <grandchild desc="Sneeze"/> 
     <grandchild desc="Spin"> 
      <ggchild desc="Run"> 
       <gggchild desc="Walk"/> 
      </ggchild> 
     </grandchild 
    </child> 
</Event> 

это то, что я придумал, но это не является динамическим

SELECT XMLELEMENT 
     ("Event",     
      (
       SELECT XMLAGG 
       (
        XMLELEMENT 
        (
         "CHILD", 
         XMLATTRIBUTES 
         (oc2.description as "desc"), 
         XMLFOREST 
         (
          oc2.description as "desc" 
         ) 
        ) 
       ) 
       FROM table1 OC2 
       WHERE OC2.CASE_CODE_TYPE = OC.CASE_CODE_TYPE 
        AND OC2.HIERARCHY_LEVEL =2    
      )   
     ) AS "RESULT" 
FROM table1 oc 
WHERE oc.HIERARCHY_LEVEL = 1 and oc.TYPE = 'Event'; 

как вы можете видеть, у меня есть жесткий код иерархии_уровня, чтобы получить первого ребенка. теперь я не хочу делать это на любом другом уровне. потому что если у него 8, то я должен повторить 8 раз. Поэтому, если кто-то может помочь указать мне в правильном направлении, чтобы сделать эту динамику, я действительно ценю это.
Благодарим за помощь.

+0

Загляните сюда, он должен вас начать: http://allthingsoracle.com/generating-xml-from-sql-and-pl-sql-part-1/ – Donal

+0

извините Донал, я только что обновил вопрос, надеюсь это поможет вам помочь мне. Спасибо – user3731575

+0

Какова связь между родителем и дочерним элементом - есть ли идентификатор столбца первичного ключа и столбец PARENT_ID или что-то связать родителя и ребенка? Как Снейдж знает, что это ребенок кашля? Если это динамическое, трудно сделать теги Grandchild, GGChild, G3Child, G4Child - это требование? Разве не достаточно, чтобы все теги назывались Child, но вложены друг в друга в иерархии? И последний вопрос: какая версия базы данных Oracle? –

ответ

0
select 
    xmltype('<event>'||dbms_xmlgen.convert(xmlagg(xmlelement(e,open_tag ||' desc="'||description||'"'||close_tags)).extract('//text()').getclobval(),1)||'</event>') out_xml 
    from 
    (
    select e.* 
    ,case 
     when tt>hierarchy_level then '>' 
--Oracle 10g 
       else '/>'||(select to_char(dbms_xmlgen.convert(xmlagg(xmlelement("e",'</'||case level when 2 then 'grand' else lpad('g',level-1,'g') end||'child>') order by level desc).extract('//text()').getClobVal(),1)) from dual where level>=tt connect by level<hierarchy_level) 
--Oracle 11g 
--  else '/>'||(select listagg('</'||case level when 2 then 'grand' else lpad('g',level-1,'g') end||'child>') within group(order by level desc) from dual where level>=tt connect by level<hierarchy_level) 
    end close_tags 
    from 
    (
     select 
       s.* 
       ,'<'||case hierarchy_level when 2 then 'grand' else lpad('g',hierarchy_level-1,'g') end||'child' open_tag 
       ,lead(hierarchy_level,1,1) over (order by to_char(root),hierarchy_level) tt from table1 s 
     order by to_char(root),s.hierarchy_level 
    )e 
    ) 

Этот запрос работает на вашем примере. Если результат xml всегда меньше 4000 символов, вы можете заменить xmlagg и dbms_convert на listagg.

+0

когда я запускаю запрос, я получаю сообщение об ошибке [Ошибка] Выполнение (8: 122): ORA-00923: FROM ключевое слово не найдено там, где ожидалось , а слово winthin group - hightighted. – user3731575

+0

Я обновил ответ с помощью решения Oracle 10g. Вместо xmlagg вы можете написать свою собственную функцию агрегации строк http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php – ksa

Смежные вопросы