Oracle функция для извлечения данных из XMLTABLE - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь написать функцию в Oracle, которая позволит мне указать имена тегов и получить обратно одно значение c. Итак, если приведенный ниже фрагмент является частью моего XML, я хочу отправить путь, порядковый номер и указать поле c, которое я хочу, и получить значение обратно.

<variables>
<variablesList>
    <sequence>1</sequence>
    <variableType>C1SQ</variableType>
    <missingValueAction>C1ER</missingValueAction>
    <defaultValue>0</defaultValue>
    <uom>KWB</uom>
    <tou>SUMMER</tou>
    <serviceQuantityToUse>C1BI</serviceQuantityToUse>
    <targetCalcLines/>
</variablesList>
<variablesList>
    <sequence>2</sequence>
    <variableType>C1SQ</variableType>
    <missingValueAction>C1ER</missingValueAction>
    <defaultValue>0</defaultValue>
    <uom>KWB</uom>
    <tou>WINTER</tou>
    <serviceQuantityToUse>C1BI</serviceQuantityToUse>
    <targetCalcLines/>
</variablesList>

Моя функция заголовок определяется следующим образом:

CREATE OR REPLACE function cm_get_bo_data_TableValue (pTableTag varchar2, pFieldTag varchar2, pSequence varchar2, pBODataValue CLOB)

Я вызываю функцию следующим образом:

select BO_DATA_AREA
 , cm_get_bo_data_TableValue ('/root/variables/variablesList', 'tou', '2', BO_DATA_AREA)
from CM_CI1558A_BO_DATA_AUDIT

Но это работает только для 'tou', потому что я не могу поместить переменную в PATH.

Итак, если у меня есть следующее, он вернет значение:

select TagValue into v_value
from dual, XMLTable(pTableTag PASSING XMLTYPE( to_clob('<root>') || pBODataValue || '</root>' ) 
                  COLUMNS sequence_num          VARCHAR2(10)    PATH 'sequence',
                          TagValue              VARCHAR2(10)    PATH 'tou'
    
) t
where sequence_num = pSequence;

return v_value;

, но если я заменю это 'tou' на pFieldTag, он говорит SQL ошибочен и сообщает мне, что ожидал строку.

                              TagValue              VARCHAR2(10)    PATH pFieldTag

Я хочу иметь возможность указать каждый конкретный тег c и вернуть значение; Мне нужно работать с ними по одному, и мне нужно что-то общее c, которое будет работать не только для этой c XML структуры.

Другими словами, я хочу иметь возможность укажите последовательность 1 для tou и получите 'SUMMER', последовательность 2 для uom и получите 'KWB' и последовательность 1 для совершенно другого тега и структуры и получите это значение тоже - для любого из значений таблицы, с которыми мы можем столкнуться (есть несколько).

1 Ответ

1 голос
/ 09 июля 2020

Для этого даже не нужно создавать специальную функцию, так как Oracle имеет очень хорошую функцию xmlquery. Например, если вы хотите получить какое-либо значение из xmltype с помощью xquery:

xmlcast (xmlquery ('/ root / variables / variablesList [2] / tou' - <== ваш путь, из вашего вопроса, передаваемого xmltype (xmldata), возвращающий содержимое) как varchar2 (100)) res </p>

Полный пример:

with test_table(xmldata) as (
select 
q'[
<variables>
<variablesList>
    <sequence>1</sequence>
    <variableType>C1SQ</variableType>
    <missingValueAction>C1ER</missingValueAction>
    <defaultValue>0</defaultValue>
    <uom>KWB</uom>
    <tou>SUMMER</tou>
    <serviceQuantityToUse>C1BI</serviceQuantityToUse>
    <targetCalcLines/>
</variablesList>
<variablesList>
    <sequence>2</sequence>
    <variableType>C1SQ</variableType>
    <missingValueAction>C1ER</missingValueAction>
    <defaultValue>0</defaultValue>
    <uom>KWB</uom>
    <tou>WINTER</tou>
    <serviceQuantityToUse>C1BI</serviceQuantityToUse>
    <targetCalcLines/>
</variablesList>
</variables>
]'
from dual
)
select
  xmlcast(
     xmlquery(
        '&input_path[&input_sequence]/&input_tag/text()'
         passing xmltype(xmldata)
         returning content
     )
     as varchar2(100)
   ) res
from test_table
/

Как вы можете видеть в этом примере, я строю путь из переменных подстановки, как вы запрошено, ie "путь [последовательность] / тег". Итак, вам нужно будет ввести:

input_path: /variables/variablesList
input_sequence: 2
input_tag: tou

PS. В этом примере я не добавляю тег, поэтому я не указываю / root в начале (зачем он вам? У вас нет действительного xml (без родительского тега) в качестве ввода?)

...