Oracle XMLTable- извлечение столбца из родительского узла

У меня есть следующая структура XML:

<root>
    <parent>
         <parent_id>1</parent_id>
         <parent_value>10000</parent_value>
         <child>
              <child_id>11</child_id>
              <other_value>1000</other_value>
         </child>
         <child>
              <child_id>12</child_id>
              <other_value>1000</other_value>
         </child>
    </parent>
</root>

Ожидаемый результат:

  CHILD_ID PARENT_VALUE
---------- ------------
        11 10000            
        12 10000            

Что я пробовал:

WITH xtbl AS (SELECT xmltype ('<root>
                    <parent>
                         <parent_id>1</parent_id>
                         <parent_value>10000</parent_value>
                         <child>
                              <child_id>11</child_id>
                              <other_value>1000</other_value>
                         </child>
                         <child>
                              <child_id>12</child_id>
                              <other_value>1000</other_value>
                         </child>
                    </parent>
                </root>') AS xcol FROM dual)
      SELECT myXmlTable.*
        FROM xtbl
             CROSS JOIN
             xmltable ('/root/parent/child'
                       PASSING xcol
                       COLUMNS child_id NUMBER (5) PATH 'child_id',
                               parent_value NUMBER (10) PATH './parent_value') myXmlTable;

Проблема с моим запросом в том, что parent_value приходит к нулю. Пожалуйста помоги.

3 ответа

Решение

Ты ищешь ./parent_node, который является <parent_node> под текущим <child> узел. И этого не существует.

Вам просто нужно подняться на уровень:

parent_value NUMBER (10) PATH './../parent_value'

Демо с вашим CTE и только что добавленным ../:

WITH xtbl AS (SELECT xmltype ('<root>
                    <parent>
                         <parent_id>1</parent_id>
                         <parent_value>10000</parent_value>
                         <child>
                              <child_id>11</child_id>
                              <other_value>1000</other_value>
                         </child>
                         <child>
                              <child_id>12</child_id>
                              <other_value>1000</other_value>
                         </child>
                    </parent>
                </root>') AS xcol FROM dual)
      SELECT myXmlTable.*
        FROM xtbl
             CROSS JOIN
             xmltable ('/root/parent/child'
                       PASSING xcol
                       COLUMNS child_id NUMBER (5) PATH 'child_id',
                               parent_value NUMBER (10) PATH './../parent_value') myXmlTable;

  CHILD_ID PARENT_VALUE
---------- ------------
        11        10000
        12        10000

Я не знаю, является ли это самой оптимизированной или самой короткой версией, но она работает:

WITH xtbl AS (SELECT xmltype ('<root>
                    <parent>
                         <parent_id>1</parent_id>
                         <parent_value>10000</parent_value>
                         <child>
                              <child_id>11</child_id>
                              <other_value>1000</other_value>
                         </child>
                         <child>
                              <child_id>12</child_id>
                              <other_value>1000</other_value>
                         </child>
                    </parent>
                </root>') AS xcol FROM dual)
      SELECT myXmlTable.*
        FROM xtbl
             CROSS JOIN
             XMLTABLE ('for $c in /root/parent/child 
                          return <child parent_value="{$c/../parent_value}">{$c}</child>'
                       PASSING xcol COLUMNS 
                       child_id NUMBER (5) PATH 'child/child_id',
                       parent_value NUMBER (10) PATH '@parent_value'
                       ) myXmlTable;

У нас была такая же проблема с Oracle 12.2.0.1.0 - то есть запрос PLSQL не возвращал значения родительского узла из данных XML с использованием синтаксиса ./../. В нашем случае подсказка MATERIALIZE вызвала возврат нулевых значений - не знаю почему, но когда подсказка была удалена, проблема с родительским узлом исчезла.

Другие вопросы по тегам