альтернатива listagg в Oracle?
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_T типа CLOB!
создать функция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: значение атрибута или элемента больше, чем указано в типе
есть ли решение для этого?
спасибо вам
6 ответов
использовать собрать или напишите свою собственную функцию агрегации.
вы можете решить 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;
вы можете посмотреть на пользовательские агрегатные функции.
приемов различно строку агрегации показаны здесь. Они включают пример для пользовательских агрегатных функций.
WM_CONCAT работал на меня.
SELECT replace(WMSYS.WM_CONCAT(myTable.name), ',', ';')
FROM myTable
GROUP BY myTable.id
я обернул его "заменить", чтобы указать другой разделитель элементов (';') от того, который используется WM_CONCAT (',').
используйте xmlAgg, пример показан ниже:
SELECT RTRIM(XMLAGG(XMLELEMENT(E,colname,',').EXTRACT('//text()') ORDER BY colname).GetClobVal(),',') AS LIST
FROM tablename;
это вернет значение clob и поэтому не нужно создавать пользовательскую функцию.
-- Создание Типа Clobe -- СОЗДАНИЕ ИЛИ ЗАМЕНА ТИПА "MSCONCATIMPL_CLOB" В КАЧЕСТВЕ ОБЪЕКТА ( resultstring типа CLOB, разделитель VARCHAR2(10),
STATIC FUNCTION odciaggregateinitialize ( io_srccontext IN OUT msconcatimpl_clob ) RETURN NUMBER,
MEMBER FUNCTION odciaggregateiterate (
self IN OUT msconcatimpl_clob,
value IN CLOB
) RETURN NUMBER,
MEMBER FUNCTION odciaggregateterminate (
self IN msconcatimpl_clob,
o_returnvalue OUT CLOB,
i_flags IN NUMBER
) RETURN NUMBER,
MEMBER FUNCTION odciaggregatemerge (
self IN OUT msconcatimpl_clob,
i_ctx2 IN msconcatimpl_clob
) RETURN NUMBER
); / -- Создание Тела Типа Clobe --
СОЗДАТЬ ИЛИ ЗАМЕНИТЬ ТЕЛО ТИПА "MSCONCATIMPL_CLOB" Статическая функция odciaggregateinitialize (io_srccontext в OUT msconcatimpl_clob ) возвращаемый номер ЕСТЬ НАЧИНАТЬ io_srccontext := msconcatimpl_clob( НОЛЬ, НОЛЬ ); io_srccontext.разделитель := ' '; Возвращение odciconst.успех; END odciaggregateinitialize;
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 (input VARCHAR2 ) возврат CLOB PARALLEL_ENABLE Совокупный используя msconcatimpl_clob; /