2012-02-23 24 views
13

listagg es una función introducida en Oracle 11.2! Ahora bien, esta función está molestando nos asignamos, estamos migrando de MySQL a Oracle y que tiene la siguiente consulta:alternativa a listagg en 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; 

es funciona bien en MySQL por lo que sabemos lo que nos molesta es menor de Oracle que devuelve VARCAR y no ¡CLOB como lo necesitamos! el texto es enorme y necesitamos que sea CLOB!

¡esto es lo que traté de hacer!

crear una tabla CLOB_T de tipo CLOB!

continuación, crear la función

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; 

ahora si lo ejecuto:

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; 

consigo

ORA-22814: valor de atributo o elemento es mayor que la especificada en el tipo

¿hay alguna solución para ello?

le da las gracias

Respuesta

14
+1

+1 ¡gracias por el enlace de recopilación! – tbone

+0

Escribí mi propia función y actualicé mi pregunta, por favor revise mi pregunta nuevamente, gracias –

+0

No sé por qué está recibiendo ese error; sin embargo, probablemente valga la pena publicarlo como una nueva pregunta, obtendrá más personas mirándolo de esa manera. –

2

Es posible que desee consultar user-defined aggregate functions.

Se muestran las técnicas de agregación de cadenas Differnt here. Incluyen un ejemplo para funciones agregadas definidas por el usuario.

+0

Buen conjunto de opciones allí. ¿Hay alguna información sobre cuáles son más rápidos? –

+0

No tengo ninguna información sobre el rendimiento. Supongo que depende principalmente del plan de ejecución general y de cómo se ajustan a ese plan de ejecución. Por lo tanto, puede diferir de una consulta a otra. – Codo

2

puede resolver el error ORA-22814 utilizando MULTISET en lugar 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

WM_CONCAT trabajó para mí.

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

me envolvió con una "reemplazar" para especificar un separador diferente material (';') de la utilizada por WM_CONCAT ('').

+2

Tenga en cuenta que WM_CONCAT no está disponible en 12c, Express Edition ni en ninguna base de datos donde Workspace Manager no esté instalado. –

+1

no está soportado ni documentado hoy en día –

1

Uso XMLAGG, se muestra el siguiente ejemplo:

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

Esto devolverá el valor CLOB y por lo tanto no hay necesidad de crear función personalizada.

0

- Creación Clobe Tipo - crear o sustituir TIPO "MSCONCATIMPL_CLOB" TAL COMO OBJETO ( resultstring CLOB, delimitador 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 

); / - Creación Clobe tipo de cuerpo -

crear o sustituir el tipo de cuerpo "MSCONCATIMPL_CLOB" ES ESTÁTICO odciaggregateinitialize FUNCIÓN (io_srccontext IN OUT msconcatimpl_clob) NÚMERO DE RETORNO SE COMENZAR io_srccontext: = msconcatimpl_clob ( NULL, NULL ); io_srccontext.delimiter: = ''; RETORNO 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; /

- Creación de Función Clobe -

CREAR O SUSTITUIR ms_concat_clob FUNCIÓN (entrada VARCHAR2) CLOB RETURN PARALLEL_ENABLE TOTAL USO msconcatimpl_clob; /