在Oracle

时间:2017-03-31 21:15:22

标签: oracle oracle12c oracle-xml-db

我正在尝试查询表中的XMLtype字段,该表的元素名称在每次出现时递增1。这些元素可能有1到多个级别,我想知道是否有一种方法可以对元素名称进行通配符,因此它会根据名称搜索返回所有元素值,而不是将所有可能的名称级别合并在一起?在找出这一步之后,我正在寻找listagg或连接结果。

select extractvalue(myXMLfield,'/doc/name1') from myTable
union
select extractvalue(myXMLfield,'/doc/name2') from myTable
union
select extractvalue(myXMLfield,'/doc/name3') from myTable

对元素名称

进行某种通配符搜索
select extractvalue(myXMLfield,'/doc/name%') from myTable

XML示例

<doc><name1>NAME_1</name1><name2>NAME_2</name2><name3>NAME_3</name3></doc>

所需的SQL查询varchar连接输出

"NAME_1,NAME_2,NAME_3"

1 个答案:

答案 0 :(得分:2)

您可以使用XMLTable提取多个节点值,并使用XPath中的子字符串模式对通配符进行通配符(根据实际数据设置适当的列大小):

select x.name
from myTable t
cross join XMLTable(
  '/doc/*[substring(name(), 1, 4) = "name"]'
  passing myXMLfield
  columns name varchar2(20) path '.'
) x;

NAME                
--------------------
NAME_1
NAME_2
NAME_3

然后您可以使用listagg()作为最终输出:

select listagg(x.name, ',') within group (order by null) as names
from myTable t
cross join XMLTable(
  '/doc/*[substring(name(), 1, 4) = "name"]'
  passing myXMLfield
  columns name varchar2(20) path '.'
) x;

NAMES                         
------------------------------
NAME_1,NAME_2,NAME_3

按null排序并不理想;如果您的真实数据具有其他属性或值,您可以提取并使用可能更好的排序。如果不是,你可以使用'name'之后的部分,假设它实际上总是数字,通过另一个子字符串:

select listagg(x.name, ',') within group (order by x.id) as names
from myTable t
cross join XMLTable(
  '/doc/*[substring(name(), 1, 4) = "name"]'
  passing myXMLfield
  columns name varchar2(20) path '.',
    id number path 'substring(name(.), 5)'
) x;