альтернатива листаггу в Oracle? - PullRequest
15 голосов
/ 23 февраля 2012

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 ]

18 голосов
/ 23 февраля 2012
3 голосов
/ 12 февраля 2013

WM_CONCAT работал для меня.

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

Я обернул его "заменить", чтобы указать другой разделитель элементов (';') из того, который используется WM_CONCAT (',').

2 голосов
/ 22 декабря 2015

Использовать xmlAgg, пример показан ниже:

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

Это вернет значение clob, поэтому нет необходимости создавать пользовательскую функцию.

2 голосов
/ 29 февраля 2012

Вы можете устранить ошибку 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 голосов
/ 23 февраля 2012

Возможно, вы захотите взглянуть на определяемые пользователем агрегатные функции .

Здесь показаны различные методы агрегирования строк . Они включают пример пользовательских статистических функций.

0 голосов
/ 12 октября 2017

- Создание типа Clobe - СОЗДАТЬ ИЛИ ЗАМЕНИТЬ ТИП «MSCONCATIMPL_CLOB» КАК ОБЪЕКТ ( Результаты 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" IS СТАТИЧЕСКАЯ ФУНКЦИЯ odciaggregateinitialize (io_srccontext IN OUT msconcatimpl_clob) НОМЕР ВОЗВРАТА ЯВЛЯЕТСЯ НАЧАТЬ io_srccontext: = msconcatimpl_clob ( НОЛЬ, НОЛЬ ); io_srccontext.delimiter: = ''; ВОЗВРАТ odciconst.success; 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;

END; /

- Создание функции Clobe -

ФУНКЦИЯ СОЗДАНИЯ ИЛИ ЗАМЕНЫ ms_concat_clob (input VARCHAR2) RETURN CLOB PARALLEL_ENABLE Совокупное использование msconcatimpl_clob; /

...