Oracle 中 listagg 的替代品?

问题描述 投票:0回答:6

listagg是Oracle 11.2中引入的函数!现在这个函数正在困扰我们分配,我们正在从 MySQL 迁移到 Oracle,我们有这个查询:

SELECT
    p_id,
    MAX(registered) AS registered,
    listagg(MESSAGE, ' ') within GROUP (ORDER BY registered) AS MESSAGE
  FROM
    umm_parent_id_remarks_v m
  GROUP BY
    m.p_id;
据我们所知,它在 MySQL 中运行良好 困扰我们的是在 Oracle 下它返回 VARCAR 而不是我们需要的 CLOB!

文本很大,我们确实需要它是 CLOB

这就是我尝试做的!

创建 CLOB 类型的 CLOB_T 表!

然后创建函数

create or replace function listaggclob (t in clob_t) return clob as ret clob := ''; i number; begin i := t.first; while i is not null loop if ret is not null then ret := ret || ' '; end if; ret := ret || t(i); i := t.next(i); end loop; return ret; end;

现在如果我运行它:

SELECT p_id, MAX(registered) AS registered, listaggclob(cast(collect (MESSAGE) as clob_t)) MESSAGE FROM umm_parent_id_remarks_v m GROUP BY m.p_id;

我明白了

ORA-22814: 属性或元素值大于类型中指定的值

有什么解决办法吗?

谢谢你

sql oracle varchar clob
6个回答
18
投票
使用

collect编写自己的聚合函数


4
投票
使用xmlAgg,示例如下:

SELECT RTRIM(XMLAGG(XMLELEMENT(E,colname,',').EXTRACT('//text()') ORDER BY colname).GetClobVal(),',') AS LIST FROM tablename;

这将返回 clob 值,因此无需创建自定义函数。


2
投票
您可以使用

ORA-22814

 而不是 
MULTISET
 来解决 
COLLECT
 错误:

SELECT p_id, MAX(registered) AS registered, listaggclob(cast(multiset( select MESSAGE from umm_parent_id_remarks_v where umm_parent_id_remarks_v.p_id = m.p_id ) as clob_t)) MESSAGE FROM umm_parent_id_remarks_v m GROUP BY m.p_id;
    

2
投票
您可能想查看

用户定义的聚合函数

此处

显示了不同的字符串聚合技术。它们包括用户定义聚合函数的示例。


1
投票

SELECT replace(WMSYS.WM_CONCAT(myTable.name), ',', ';') FROM myTable GROUP BY myTable.id

我用“replace”包裹它,以指定与 WM_CONCAT 使用的项目分隔符(';')不同的项目分隔符(',')。 


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.