在Oracle查询中串联XMLType节点

时间:2019-04-02 10:11:03

标签: xml oracle

我有一个包含XML类型数据的CLOB列。例如XML数据是:

<A><B>123</b><C>456</C><B>789</b></A>

我尝试了concat函数:

concat(xmltype (a.xml).EXTRACT ('//B/text()').getStringVal (),';'))

xmltype (a.xml).EXTRACT (concat('//B/text()',';').getStringVal ()))

但是他们给“;”仅在每个<B>标签之后才结束。

我当前正在使用

xmltype (a.xml).EXTRACT ('//B/text()').getStringVal () 

我想将所有<B>;连接起来,预期结果应该是123;789

请建议我如何连接数据。

1 个答案:

答案 0 :(得分:2)

concat() SQL函数连接两个值,因此它只是将分号独立地附加到每个提取的值上。但是,您实际上是在尝试对结果进行字符串聚合(可能实际上是两个以上的提取值)。

您可以使用XMLQuery而不是提取,并使用XPath string-join()函数进行合并:

XMLQuery('string-join(/A/B, ";")' passing xmltype(a.xml) returning content)

具有固定XMl终端节点标签的演示:

-- CTE for sample data
with a (xml) as (
  select '<A><B>123</B><C>456</C><B>789</B></A>' from dual
)
-- actual query
select XMLQuery('string-join(/A/B, ";")' passing xmltype(a.xml) returning content) as result
from a;

RESULT
------------------------------
123;789

您还可以使用XMLTable提取所有单独的<B>值,然后使用SQL级聚合:

-- CTE for sample data
with a (xml) as (
  select '<A><B>123</B><C>456</C><B>789</B></A>' from dual
)
-- actual query
select listagg(x.b, ';') within group (order by null) as result
from a
cross join XMLTable('/A/B' passing xmltype(a.xml) columns b number path '.') x;

RESULT
------------------------------
123;789

这为您提供了更大的灵活性,并且可以更轻松地按其他节点值进行分组,但是根据您的示例值,这里似乎并不需要。