web-dev-qa-db-fra.com

alternative à listagg dans Oracle?

listagg est une fonction introduite dans Oracle 11.2! maintenant, cette fonction nous pose problème, nous passons de MySQL à Oracle et nous avons cette requête:

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;

cela fonctionne très bien dans MySQL dans la mesure où nous savons que nous avons des problèmes avec Oracle, il retourne VARCAR et pas CLOB comme nous en avons besoin! le texte est énorme et nous en avons besoin d'être CLOB !

voici ce que j'ai essayé de faire!

créer une table CLOB_T de type CLOB!

puis créer la fonction

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;

maintenant si je le lance:

  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;

Je reçois

ORA-22814: la valeur de l'attribut ou de l'élément est supérieure à celle spécifiée dans le type

y a-t-il une solution pour cela?

merci

14
Data-Base
16
Colin Pickard

WM_CONCAT a travaillé pour moi.

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

Je l'ai enveloppé d'un "remplacer" pour spécifier un séparateur d'élément différent (';') de celui utilisé par WM_CONCAT (','). 

3
Marco Zecca

Utilisez xmlAgg, l'exemple ci-dessous:

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

Cela retournera la valeur de clob et donc pas besoin de créer une fonction personnalisée.

2
Ankur Bhutani

Vous voudrez peut-être examiner fonctions d'agrégation définies par l'utilisateur .

Les techniques d’agrégation de chaînes differnt sont montrées ici . Ils incluent un exemple pour les fonctions d'agrégat définies par l'utilisateur.

2
Codo

Vous pouvez résoudre l'erreur ORA-22814 en utilisant MULTISET au lieu de 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
Jon Heller

- Création d'un type de clobe - CREATE OR REMPLACER LE TYPE "MSCONCATIMPL_CLOB" COMME OBJET ( Resultstring CLOB, délimiteur 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

); / - Création d’un corps de type clobe -

CREATE OR REMPLACER LE CORPS DE TYPE "MSCONCATIMPL_CLOB" IS FONCTION STATIQUE odciaggregateinitialize (io_srccontext IN OUT msconcatimpl_clob) NUMERO DE RETOUR EST . = msconcatimpl_clob ( NULL, NULL ); io_srccontext.delimiter: = ''; RETOUR odciconst.success; FIN 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;

FIN;/

- Création d'une fonction Clobe -

CREATE OR REPLACE FUNCTION ms_concat_clob (entrée VARCHAR2) RETURN CLOB PARALLEL_ENABLE AGREGATE EN UTILISANT msconcatimpl_clob; /

0
Javed Khan