listagg is a function introduced in Oracle 11.2! now this function is bugging us allot, we are migrating from MySQL to Oracle and we have this query:
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;
is works fine in MySQL as far as we know what bugging us is under Oracle it returns VARCAR and not CLOB as we need! the text is huge and we do need it to be CLOB!
here is what I tried to do!
create a CLOB_T table of CLOB Type!
then create the function
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;
now if I run it:
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;
I get
ORA-22814: attribute or element value is larger than specified in type
is there any solution for it?
thanks you
-- Creating Clobe Type -- CREATE OR REPLACE TYPE "MSCONCATIMPL_CLOB" AS OBJECT ( resultstring CLOB, delimiter VARCHAR2(10),
); / -- Creating Clobe Type Body --
CREATE OR REPLACE TYPE BODY "MSCONCATIMPL_CLOB" IS STATIC FUNCTION odciaggregateinitialize ( io_srccontext IN OUT msconcatimpl_clob ) RETURN NUMBER IS BEGIN io_srccontext := msconcatimpl_clob( NULL, NULL ); io_srccontext.delimiter := ' '; RETURN odciconst.success; END odciaggregateinitialize;
END; /
-- Creating Clobe Function --
CREATE OR REPLACE FUNCTION ms_concat_clob ( input VARCHAR2 ) RETURN CLOB PARALLEL_ENABLE AGGREGATE USING msconcatimpl_clob; /
You might want to look at user-defined aggregate functions.
Differnt string aggregation techniques are shown here. They include an example for user-defined aggregate functions.
You can solve the
ORA-22814
error by usingMULTISET
instead ofCOLLECT
:Use collect or write your own aggregation function.
WM_CONCAT worked for me.
I wrapped it with a "replace" to specify a different item separator (';') from the one used by WM_CONCAT (',').
Use xmlAgg, example is shown below:
This will return clob value and so no need to create custom function.