2015-04-21 25 views
6

Creata una vista in cui un campo (di 6) è una concatenazione di due campi dalla tabella di origine. Creata una seconda vista che utilizza listagg per combinare potenzialmente i risultati della concatenazione. L'utilizzo di questa operazione in due passaggi restituisce correttamente la concatenazione listagg dei due campi dalla tabella di origine.Oracle - ORA-01489: il risultato della concatenazione di stringhe è troppo lungo

Quando provo a creare una vista che produrrà sia la concatenazione che il listagg, ottengo l'errore oracle ora-01489 Il risultato della concatenazione di stringhe è troppo lungo.

Come prova, ho selezionato massima (lunghezza (campo concatenato) e che ha restituito 837. Così l'errore indicato è in errore, a quanto pare.

Così deve essere nella sintassi. Ho provato rtrim, assetto e anche substr, ma non è possibile ottenere l'istruzione di visualizzazione sia per compilare listagg (concatenazione) sia per restituire dati

Che io sia in grado di sviluppare le due viste che restituiscono correttamente i dati suggerisce che ho la sintassi di base in basso, ma il compito di combinare la concatenazione con la funzione listagg che non sono stato in grado di capire

In un si separato tuation, sono stato in grado di combinare la concatenazione con la funzione listagg in una dichiarazione:

LISTAGG (STATEMENTS || ' - ' || BIRTH_DATE, '; ') 
        WITHIN GROUP (ORDER BY STATEMENTS || ' - ' || BIRTH_DATE) 
        AS GROWING_UP 

Questa sintassi restituisce correttamente i dati desiderati .........

Ma nella situazione descritta sopra, la sintassi simile crea l'errore Ora-01489.

Sapendo che a volte gli errori di Oracle possono essere fuorvianti, mi chiedo se qualche esperto di bordo possa sapere di un motivo diverso da quello che ha affermato che Oracle potrebbe lanciare questo errore?

LISTAGG ((NUMBER || '-' || text), ',') WITHIN GROUP (ORDER BY (NUMBER || '-' || text)) 
AS 
    restrictions FROM source 

restituisce l'errore

+3

Perché non hai testare SUM (lunghezza (campo concatenato))? :) –

+2

La somma è diversa da quella massima; la lunghezza più lunga di un singolo campo concatenato è 837, ma questo non ti dice per quanto tempo potrebbe essere la lista di molti di quei singoli campi concatenati. Quale penso sia ciò che l'OP sta avendo problemi. Sarebbe utile un SQL Fiddle che riproduce questo, o almeno il codice che produce l'errore - non solo il codice che funziona. –

+0

È un'osservazione abituale raggiungere il limite con 'LISTAGG' quando l'applicazione è progettata in fretta. Perché non utilizzare ** XMLAGG **? –

risposta

17

Stai superando il limite SQL di 4000 byte che si applica a LISTAGG pure.

SQL> SELECT listagg(text, ',') WITHIN GROUP (
    2 ORDER BY NULL) 
    3 FROM 
    4 (SELECT to_char(to_date(level,'j'), 'jsp') text FROM dual CONNECT BY LEVEL < 250 
    5 ) 
    6/
SELECT listagg(text, ',') WITHIN GROUP (
* 
ERROR at line 1: 
ORA-01489: result of string concatenation is too long 

Per aggirare il problema, è possibile utilizzare XMLAGG.

Ad esempio,

SQL> SET LONG 2000000 
SQL> SET pagesize 50000 
SQL> SELECT rtrim(xmlagg(XMLELEMENT(e,text,',').EXTRACT('//text()') 
    2     ).GetClobVal(),',') very_long_text 
    3 FROM 
    4 (SELECT to_char(to_date(level,'j'), 'jsp') text FROM dual CONNECT BY LEVEL < 250 
    5 ) 
    6/

VERY_LONG_TEXT 
-------------------------------------------------------------------------------- 
one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen 
,fifteen,sixteen,seventeen,eighteen,nineteen,twenty,twenty-one,twenty-two,twenty 
-three,twenty-four,twenty-five,twenty-six,twenty-seven,twenty-eight,twenty-nine, 
thirty,thirty-one,thirty-two,thirty-three,thirty-four,thirty-five,thirty-six,thi 
rty-seven,thirty-eight,thirty-nine,forty,forty-one,forty-two,forty-three,forty-f 
our,forty-five,forty-six,forty-seven,forty-eight,forty-nine,fifty,fifty-one,fift 
y-two,fifty-three,fifty-four,fifty-five,fifty-six,fifty-seven,fifty-eight,fifty- 
nine,sixty,sixty-one,sixty-two,sixty-three,sixty-four,sixty-five,sixty-six,sixty 
-seven,sixty-eight,sixty-nine,seventy,seventy-one,seventy-two,seventy-three,seve 
nty-four,seventy-five,seventy-six,seventy-seven,seventy-eight,seventy-nine,eight 
y,eighty-one,eighty-two,eighty-three,eighty-four,eighty-five,eighty-six,eighty-s 
even,eighty-eight,eighty-nine,ninety,ninety-one,ninety-two,ninety-three,ninety-f 
our,ninety-five,ninety-six,ninety-seven,ninety-eight,ninety-nine,one hundred,one 
hundred one,one hundred two,one hundred three,one hundred four,one hundred five 
,one hundred six,one hundred seven,one hundred eight,one hundred nine,one hundre 
d ten,one hundred eleven,one hundred twelve,one hundred thirteen,one hundred fou 
rteen,one hundred fifteen,one hundred sixteen,one hundred seventeen,one hundred 
eighteen,one hundred nineteen,one hundred twenty,one hundred twenty-one,one hund 
red twenty-two,one hundred twenty-three,one hundred twenty-four,one hundred twen 
ty-five,one hundred twenty-six,one hundred twenty-seven,one hundred twenty-eight 
,one hundred twenty-nine,one hundred thirty,one hundred thirty-one,one hundred t 
hirty-two,one hundred thirty-three,one hundred thirty-four,one hundred thirty-fi 
ve,one hundred thirty-six,one hundred thirty-seven,one hundred thirty-eight,one 
hundred thirty-nine,one hundred forty,one hundred forty-one,one hundred forty-tw 
o,one hundred forty-three,one hundred forty-four,one hundred forty-five,one hund 
red forty-six,one hundred forty-seven,one hundred forty-eight,one hundred forty- 
nine,one hundred fifty,one hundred fifty-one,one hundred fifty-two,one hundred f 
ifty-three,one hundred fifty-four,one hundred fifty-five,one hundred fifty-six,o 
ne hundred fifty-seven,one hundred fifty-eight,one hundred fifty-nine,one hundre 
d sixty,one hundred sixty-one,one hundred sixty-two,one hundred sixty-three,one 
hundred sixty-four,one hundred sixty-five,one hundred sixty-six,one hundred sixt 
y-seven,one hundred sixty-eight,one hundred sixty-nine,one hundred seventy,one h 
undred seventy-one,one hundred seventy-two,one hundred seventy-three,one hundred 
seventy-four,one hundred seventy-five,one hundred seventy-six,one hundred seven 
ty-seven,one hundred seventy-eight,one hundred seventy-nine,one hundred eighty,o 
ne hundred eighty-one,one hundred eighty-two,one hundred eighty-three,one hundre 
d eighty-four,one hundred eighty-five,one hundred eighty-six,one hundred eighty- 
seven,one hundred eighty-eight,one hundred eighty-nine,one hundred ninety,one hu 
ndred ninety-one,one hundred ninety-two,one hundred ninety-three,one hundred nin 
ety-four,one hundred ninety-five,one hundred ninety-six,one hundred ninety-seven 
,one hundred ninety-eight,one hundred ninety-nine,two hundred,two hundred one,tw 
o hundred two,two hundred three,two hundred four,two hundred five,two hundred si 
x,two hundred seven,two hundred eight,two hundred nine,two hundred ten,two hundr 
ed eleven,two hundred twelve,two hundred thirteen,two hundred fourteen,two hundr 
ed fifteen,two hundred sixteen,two hundred seventeen,two hundred eighteen,two hu 
ndred nineteen,two hundred twenty,two hundred twenty-one,two hundred twenty-two, 
two hundred twenty-three,two hundred twenty-four,two hundred twenty-five,two hun 
dred twenty-six,two hundred twenty-seven,two hundred twenty-eight,two hundred tw 
enty-nine,two hundred thirty,two hundred thirty-one,two hundred thirty-two,two h 
undred thirty-three,two hundred thirty-four,two hundred thirty-five,two hundred 
thirty-six,two hundred thirty-seven,two hundred thirty-eight,two hundred thirty- 
nine,two hundred forty,two hundred forty-one,two hundred forty-two,two hundred f 
orty-three,two hundred forty-four,two hundred forty-five,two hundred forty-six,t 
wo hundred forty-seven,two hundred forty-eight,two hundred forty-nine 

Se si desidera concatenare più colonne che si hanno 4000 byte, allora è possibile concatenare l'uscita XMLAGG di ogni colonna per evitare il limite SQL di 4000 byte.

Per esempio,

WITH DATA AS 
    (SELECT 1 id, rpad('a1',4000,'*') col1, rpad('b1',4000,'*') col2 FROM dual 
    UNION 
    SELECT 2 id, rpad('a2',4000,'*') col1, rpad('b2',4000,'*') col2 FROM dual 
) 
SELECT ID, 
     rtrim(xmlagg(XMLELEMENT(e,col1,',').EXTRACT('//text()')).GetClobVal(), ',') 
     || 
     rtrim(xmlagg(XMLELEMENT(e,col2,',').EXTRACT('//text()')).GetClobVal(), ',') 
     AS very_long_text 
FROM DATA 
GROUP BY ID 
ORDER BY ID; 
+0

Grazie per la risposta. Potrei dover passare xml ... speravo di rimanere in varchar2, soprattutto perché so che nessun campo supererà la lunghezza di 837. – user761758

+0

@ user761758 Non è necessario apportare modifiche alla tabella (o allo schema). Tutto quello che devi fare è, implementare il mio suggerimento, sostituire il nome_tabella con il nome_tabella nell'esempio. Questo è tutto. Per favore segna risposta, aiuterebbe gli altri. –

+0

come hai detto, la tua risposta suggerisce una soluzione alternativa, ma in realtà non risponde alla domanda originale sul motivo per cui Oracle ha restituito l'errore in primo luogo. Vorrei sapere se qualcuno potrebbe sapere il motivo per cui l'errore è stato restituito quando sappiamo che i dati risultanti non si avvicineranno al limite di 4000 caratteri. – user761758

Problemi correlati