2012-02-23 10 views
13

listagg è una funzione introdotta in Oracle 11.2! ora questa funzione è intercettazioni noi assegniamo, stiamo migrando da MySQL a Oracle e abbiamo questa query:alternativa a listagg in 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; 

è funziona bene in MySQL per quanto sappiamo ciò che ci intercettazioni è sotto Oracle che restituisce VARCAR e non CLOB di cui abbiamo bisogno! il testo è enorme e abbiamo bisogno che sia CLOB!

ecco cosa ho provato a fare!

creare una tabella CLOB_T di tipo CLOB!

quindi creare la funzione

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; 

ora se faccio funzionare:

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; 

ottengo

ORA-22814: attributo o elemento è maggiore del valore specificato in caratteri

c'è qualche soluzione per questo?

ringrazia

risposta

14
+1

+1 grazie per il link di raccolta! – tbone

+0

Ho scritto la mia funzione e ho aggiornato la mia domanda, per favore rivedi la mia domanda di nuovo, grazie –

+0

Non so perché stai ricevendo quell'errore - probabilmente vale la pena di postarlo come una nuova domanda, ma otterrai più persone guardandolo in quel modo. –

2

Si potrebbe voler guardare user-defined aggregate functions.

Differnt le tecniche di aggregazione di stringhe sono mostrate here. Includono un esempio per le funzioni di aggregazione definite dall'utente.

+0

Buona serie di opzioni lì. C'è qualche informazione su quali sono più veloci? –

+0

Non ho alcuna informazione sulle prestazioni. Immagino che dipenda principalmente dal piano generale di esecuzione e dal modo in cui si inseriscono in quel piano di esecuzione. Quindi potrebbe differire da query a query. – Codo

2

È possibile risolvere l'errore ORA-22814 utilizzando MULTISET invece di 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 ha lavorato per me.

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

ho avvolto con un "sostituire" per specificare un separatore diverso elemento (';') da quello usato da WM_CONCAT ('').

+2

Si noti che WM_CONCAT non è disponibile in 12c, Express Edition e in qualsiasi database in cui Workspace Manager non è installato. –

+1

al giorno d'oggi non è supportato né documentato –

1

Usa xmlagg, esempio è mostrato sotto:

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

Ciò restituirà valore clob e quindi non è necessario creare funzione personalizzata.

0

- Creazione Clobe Tipo - creare o sostituire TIPO "MSCONCATIMPL_CLOB" As Object ( ResultString CLOB, delimitatore 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 

); / - Creazione Clobe Corporatura -

creare o sostituire il tipo di corpo "MSCONCATIMPL_CLOB" È STATICO FUNZIONE odciaggregateinitialize (io_srccontext IN OUT msconcatimpl_clob) andata e ritorno Numero VIENE BEGIN io_srccontext: = msconcatimpl_clob ( NULL, NULL ); io_srccontext.delimiter: = ''; RETURN 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; /

- Creazione Clobe Funzione -

GENERARE O SOSTITUIRE LA FUNZIONE ms_concat_clob (ingresso VARCHAR2) RETURN CLOB PARALLEL_ENABLE COMPLESSO DI UTILIZZARE msconcatimpl_clob; /