Sql Oracle中listagg的替代方案?
Listag是Oracle 11.2中引入的一个函数!现在,这个函数正在困扰我们allot,我们正在从MySQL迁移到Oracle,我们有一个查询:Sql Oracle中listagg的替代方案?,sql,oracle,varchar,clob,Sql,Oracle,Varchar,Clob,Listag是Oracle 11.2中引入的一个函数!现在,这个函数正在困扰我们allot,我们正在从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
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中运行良好
让我们烦恼的是,甲骨文公司将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:属性或元素值大于类型中指定的值
有什么解决办法吗
感谢您使用或。您可能需要查看
显示了不同的字符串聚合技术。它们包括一个用户定义聚合函数的示例。您可以通过使用
MULTISET
而不是COLLECT
来解决ORA-22814
错误:
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;
Wem_CONCAT为我工作
SELECT replace(WMSYS.WM_CONCAT(myTable.name), ',', ';')
FROM myTable
GROUP BY myTable.id
我用一个“replace”来包装它,以指定与WM_CONCAT(',')使用的项目分隔符(';')不同的项目分隔符 使用xmlAgg,示例如下所示:
SELECT RTRIM(XMLAGG(XMLELEMENT(E,colname,',').EXTRACT('//text()') ORDER BY colname).GetClobVal(),',') AS LIST
FROM tablename;
这将返回clob值,因此无需创建自定义函数。--创建Clobe类型--
创建或替换类型“MSCONCATIMPL_CLOB”作为对象(
结果字符串CLOB,
分隔符VARCHAR2(10)
));
/
--创建Clobe类型主体--
创建或替换类型主体“MSCONCATIMPL\u CLOB”为
静态函数odciaggregateinitialize(io_srccontext IN OUT msconcatimpl_clob)返回编号
是
开始
io_srccontext:=msconcatimpl_clob(
无效的
无效的
);
io_srccontext.delimiter:='';
返回odciconst.success;
结束ODCIaggregate初始化
MEMBER FUNCTION odciaggregateiterate (
self IN OUT msconcatimpl_clob,
value IN CLOB
) RETURN NUMBER
IS
BEGIN
IF
value IS NOT NULL
THEN
IF
self.resultstring IS NULL
THEN
self.resultstring := self.resultstring || value;
ELSE
self.resultstring := self.resultstring
|| self.delimiter
|| value;
END IF;
END IF;
RETURN odciconst.success;
END odciaggregateiterate;
MEMBER FUNCTION odciaggregateterminate (
self IN msconcatimpl_clob,
o_returnvalue OUT CLOB,
i_flags IN NUMBER
) RETURN NUMBER
IS
BEGIN
o_returnvalue := self.resultstring;
RETURN odciconst.success;
END odciaggregateterminate;
MEMBER FUNCTION odciaggregatemerge (
self IN OUT msconcatimpl_clob,
i_ctx2 IN msconcatimpl_clob
) RETURN NUMBER
IS
BEGIN
IF
self.resultstring IS NULL
AND
i_ctx2.resultstring IS NOT NULL
THEN
self.resultstring := i_ctx2.resultstring;
ELSIF
self.resultstring IS NOT NULL
AND
i_ctx2.resultstring IS NOT NULL
THEN
self.resultstring := self.resultstring
|| self.delimiter
|| i_ctx2.resultstring;
END IF;
RETURN odciconst.success;
END odciaggregatemerge;
结束;
/
--创建Clobe函数--
创建或替换函数ms_concat_clob(输入VARCHAR2)返回clob
并行_启用
使用msconcatimpl_clob进行聚合;
/我确实编写了我自己的函数,并且更新了我的问题,请再次检查我的问题,谢谢。我不知道为什么会出现这种错误-可能值得将其作为一个新问题发布,这样会让更多的人看到。这是一组很好的选项。有关于哪个更快的信息吗?我没有关于性能的信息。我想这主要取决于总体执行计划以及它们如何融入该执行计划。因此,不同的查询可能会有所不同。请注意,WM_CONCAT在12c、Express Edition和任何未安装Workspace Manager的数据库中都不可用。目前不支持也没有文档记录。Xmlagg速度非常慢。是否有快速的替代方案?
MEMBER FUNCTION odciaggregateiterate (
self IN OUT msconcatimpl_clob,
value IN CLOB
) RETURN NUMBER
IS
BEGIN
IF
value IS NOT NULL
THEN
IF
self.resultstring IS NULL
THEN
self.resultstring := self.resultstring || value;
ELSE
self.resultstring := self.resultstring
|| self.delimiter
|| value;
END IF;
END IF;
RETURN odciconst.success;
END odciaggregateiterate;
MEMBER FUNCTION odciaggregateterminate (
self IN msconcatimpl_clob,
o_returnvalue OUT CLOB,
i_flags IN NUMBER
) RETURN NUMBER
IS
BEGIN
o_returnvalue := self.resultstring;
RETURN odciconst.success;
END odciaggregateterminate;
MEMBER FUNCTION odciaggregatemerge (
self IN OUT msconcatimpl_clob,
i_ctx2 IN msconcatimpl_clob
) RETURN NUMBER
IS
BEGIN
IF
self.resultstring IS NULL
AND
i_ctx2.resultstring IS NOT NULL
THEN
self.resultstring := i_ctx2.resultstring;
ELSIF
self.resultstring IS NOT NULL
AND
i_ctx2.resultstring IS NOT NULL
THEN
self.resultstring := self.resultstring
|| self.delimiter
|| i_ctx2.resultstring;
END IF;
RETURN odciconst.success;
END odciaggregatemerge;