xml - 具有多个子节点的 Oracle XML 查询

标签 xml oracle

我想实现对 XML 元素的查询,但找不到实现此目的的合适方法。

让我们考虑一下这个表:

CREATE TABLE SUBSCRIPTIONS(
SUBSCRIPTION_ID NUMBER,
PARAMETERS_XML  CLOB
);

我的 XML 看起来像:

<Model>
  <Parameters>
    <Parameter>
      <userParameter>outlets</userParameter>
       <Values>
         <Value>45</Value>
         <Value>676</Value>
         <Value>1502</Value>
         ...
       </Values>
    </Parameter>
  </Parameters>
</Model>

我正在尝试使用以下查询从 XML、参数名称和参数值中获取每个订阅:

SELECT
s.SUBSCRIPTION_ID,
s.PARAMETERS_XML,
xt.*
FROM EFNTA.SUBSCRIPTIONS s,
XMLTABLE(
    '/Model/Parameters/Parameter'
    PASSING XMLTYPE(s.PARAMETERS_XML)
    COLUMNS USER_PARAM  VARCHAR2(100)  PATH 'userParameter',
    PARAM_VALUE VARCHAR2(1000) PATH '//*:Values',
    CHECKED_LIST_EXCLUDE VARCHAR2(100) PATH '//*:CheckedListExclude'                        
) xt ORDER BY 1 DESC;

问题是当有多个值时,结果作为一个大的串联链返回:

enter image description here

有什么简单的方法可以用逗号、分号或其他任何方式分隔这些值吗? (我事先不知道值的数量)我找不到如何使用 XPath 实现这一点。

最佳答案

您可以使用 FLOWR 将 XML 重写为包含尾随 ,在每个Value元素:

SELECT s.SUBSCRIPTION_ID,
       s.PARAMETERS_XML,
       xt.User_Param,
       RTRIM(xt.Param_Value, ',') AS Param_Value,
       xt.Checked_List_Exclude
FROM   EFNTA.SUBSCRIPTIONS s
       CROSS JOIN
       XMLTABLE(
         'copy $e := .
         modify (
           for $i in $e/Model/Parameters/Parameter/Values/Value
           return replace node $i with <Value>{$i},</Value>
         )
         return $e/Model/Parameters/Parameter'
         PASSING XMLTYPE(s.PARAMETERS_XML)
         COLUMNS
           USER_PARAM  VARCHAR2(100)  PATH 'userParameter',
           PARAM_VALUE VARCHAR2(1000) PATH '//*:Values',
           CHECKED_LIST_EXCLUDE VARCHAR2(100) PATH '//*:CheckedListExclude'
        ) xt
ORDER BY 1 DESC;

或者,按照 Pavel Koryakin 的建议, 使用 string-join() :

SELECT s.SUBSCRIPTION_ID,
       s.PARAMETERS_XML,
       xt.*
FROM   EFNTA.SUBSCRIPTIONS s
       CROSS JOIN
       XMLTABLE(
         '/Model/Parameters/Parameter'
         PASSING XMLTYPE(s.PARAMETERS_XML)
         COLUMNS
           USER_PARAM  VARCHAR2(100)  PATH 'userParameter',
           PARAM_VALUE VARCHAR2(1000) PATH 'Values/string-join(./Value/text(), ",")',
           CHECKED_LIST_EXCLUDE VARCHAR2(100) PATH '//CheckedListExclude'
        ) xt
ORDER BY 1 DESC;

这两个输出:

<表类="s-表"> <头> SUBSCRIPTION_ID PARAMETERS_XML USER_PARAM PARAM_VALUE CHECKED_LIST_EXCLUDE <正文> 1

outlets

45
676
1502



/> 奥特莱斯 45,676,1502

db<> fiddle here

关于xml - 具有多个子节点的 Oracle XML 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71950647/

相关文章:

xml - 如何使用 XSLT 获取 XML 属性的首字母?

html - 我应该将站点地图设置为什么权限?

Android:更改设备设置时的布局大小问题

java - RSS 阅读器为 ListView 创建自定义适配器

arrays - 从 PL/SQL 中的多列关联数组中删除重复项

oracle - 使用 CTE Oracle 生成日期范围

mysql - 将记录从 XML 文件插入 MySQL DB

java - JPA 实体类给出 2 个 @GenerateValue 字段的错误

linux - 有没有人有 Oracle PL/SQL 代码来将所有同义词重命名为另一个模式?

java - 哪种 Java 数据类型对应于 Oracle SQL 数据类型 NUMERIC?