在 Oracle 中查询递增 XML 元素名称

Querying incrementing XML element names in Oracle

我正在尝试查询 table 中的 XMLtype 字段,该字段的元素名称在每次出现时递增 1。这些元素可能有 1 到多个级别,我想知道是否有一种方法可以通配元素名称,这样它 return 所有基于名称搜索的元素值而不是我联合所有可能的级别一起取名?在我弄清楚这一步后,我正在寻找 listagg 或连接结果。

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

vs 对元素名称的某种通配符搜索

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"

您可以使用 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;