从 XMLTABLE 中提取数据的 Oracle 函数

Oracle function to pull data from XMLTABLE

我正在尝试在 Oracle 中编写一个函数,它允许我指定标记名称并返回一个特定的值。因此,如果下面的代码片段是我的 XML 的一部分,我想发送路径、序列号和我想要的特定字段,然后取回值。

<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。

所以,如果我有以下内容,它将 return 一个值:

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;

但是如果我用 pFieldTag 替换 'tou',它会说 SQL 是错误的,并告诉我它需要一个字符串。

                              TagValue              VARCHAR2(10)    PATH pFieldTag

我希望能够指定每个特定的标签并取回值;我需要一次一个地处理它们,并且想要一些通用的东西,而不是这个特定的 XML 结构。

换句话说,我希望能够为tou指定sequence 1并得到'SUMMER',sequence 2为uom和get 'KWB',sequence 1用于完全不同的标签和结构并获得该值 - 对于我们可能遇到的任何 table 值(有一些)。

您甚至不需要为此创建特殊函数,因为 Oracle 具有非常好的函数 xml查询。例如,如果你想通过 xquery 从 xmltype 中获取一些值:

xml投( xml查询( '/root/variables/variablesList[2]/tou' -- <== 你的路径,来自你的问题 传递 xmltype(xmldata) 返回内容 ) 作为 varchar2(100) ) 资源

完整示例:

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
/

如您在本例中所见,我正在按照您的要求从替换变量构建路径,即“路径[序列]/标签”。 所以你需要输入:

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

PS。在这个例子中我没有添加标签,所以我没有在开头指定/root(你为什么需要它?你没有输入有效的xml(没有父标签)吗?)