2013-09-26 17 views
6
Select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d) 
    from table1 

La query precedente non spooling correttamente i dati nel file di testo.ERRORE alla riga 191: ORA-01489: risultato della concatenazione di stringhe troppo lungo

che,

Select a||b||c||d 
    from table1. 

sta finendo per

ERRORE alla linea 191: ORA-01489: risultato della concatenazione stringa è troppo lungo.

Si prega di aiutare !!!

+0

Alcuni disponibili. sono suggerimenti su: http://stackoverflow.com/questions/14864055/listagg-function-and-ora-01489-result-of-string-concatenation-is-too-long – Sampath

risposta

0

Come aumentare il valore per LONG? Potrebbe essere necessario aumentare la variabile lunga a un valore più alto. Fare clic su here per la descrizione dettagliata.

Esempio:

SET LONG 100000; 
SPOOL test_clob.txt 
SELECT to_clob(lpad('A',4000,'A')) 
     ||'B' 
     ||to_clob(lpad('C',4000,'C')) 
     ||'D' 
     ||to_clob(lpad('E',4000,'E')) 
     ||'F' 
    FROM dual; 
SPOOL OFF; 

vostra seconda query restituisce l'errore perché, Il concat (||) Operatore nella query sta cercando di tornare VARCHAR2, che ha limite di 4000 caratteri e ottenere superato.

+1

È SET LONG un parametro di sistema o lo fa funziona solo per la query che viene avviata? –

+1

@DavideInglima Dalla documentazione: * "L'istruzione SET assegna valori a diversi tipi di variabili che influiscono sul funzionamento del server o del client." * –

-1

SQL * Oltre a 80 righe in modalità hardcode durante la visualizzazione di CLOB, non sembra esserci alcun modo per aggirarlo. Pertanto, se si desidera generare un file csv da caricare in altri database, si avrà il problema di analizzare queste nuove righe aggiuntive.

La soluzione definitiva è l'utilizzo di PL/SQL. Ad esempio, per GENERATE un file CSV delimitato da virgole da tavolo "xyz", utilizzare il seguente codice:

set lin 32766 
set serveroutput on size unlimited 

DECLARE 
    TYPE arraytable IS TABLE OF xyz%ROWTYPE; 
    myarray arraytable; 
    CURSOR c IS 
    select * from xyz ; 
BEGIN 
    OPEN c; 
    LOOP 
     FETCH c BULK COLLECT INTO myarray LIMIT 10000; 
     FOR i IN 1 .. myarray.COUNT 
      LOOP 
       DBMS_OUTPUT.PUT_LINE(
        myarray(i).col1||','|| 
        myarray(i).col2||','|| 
        myarray(i).col3||','|| 
        myarray(i).col4; 
     END LOOP; 
     EXIT WHEN c%NOTFOUND; 
    END LOOP; 
END; 
/

Un bonus di questo approccio è che questo funziona anche con tipo di dati LONG!

+0

Si sta ancora concatenando VARCHAR> 4000 byte. –

+0

@ Jean-Francois Savard, No. L'output di PL/SQL non è più VARCHAR. Pertanto non sarà limitato dalla limitazione di 4000 dimensioni. – user3398079

-1

Prova la funzione xmlagg. Questo ha funzionato bene per me quando ho riscontrato un problema simile.

http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions215.htm

+3

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. – OhBeWise

1

VARCHAR2 sono limitati a 4000 byte. Se si ottiene questo errore

ERRORE alla linea 191: ORA-01489: risultato della concatenazione di stringhe è troppo lungo.

Quindi è abbastanza chiaro che la concatenazione supera i 4000 byte.

Ora cosa fare?

La prima soluzione per utilizzare CLOB è corretta.

select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d) 

sembra che il problema vero è il risparmio di presentare

Sopra query non è lo spooling i dati correttamente in file di testo.

Mentre non hai pubblicato come salvare il clob risultante in un file, credo che non lo stai facendo correttamente.Se si tenta di salvare in un file nello stesso modo in cui lo si faceva con VARCHAR2, lo si sta facendo male.

È necessario prima utilizzare dbms_lob.read per leggere il clob dal database, quindi utilizzare utl_file.put_raw per scrivere su file.

DECLARE 
    position NUMBER := 1; 
    byte_length NUMBER := 32760; 
    length NUMBER; 
    vblob BLOB; 
    rawlob RAW(32760); 
    temp NUMBER; 
    output utl_file.file_type; 
BEGIN 
    -- Last parameter is maximum number of bytes returned. 
    -- wb stands for write byte mode 
    output := utl_file.fopen('DIR', 'filename', 'wb', 32760); 

    position := 1; 
    select dbms_lob.getlength(yourLob) 
    into len 
    from somewhere 
    where something; 

    temp := length; 

    select yourLob 
    into vlob 
    from somewhere 
    where something; 

    IF len < 32760 THEN 
     utl_file.put_raw(output, vblob); 
     -- Don't forget to flush 
     utl_file.fflush(output); 
    ELSE -- write part by part 
     WHILE position < len AND byte_length > 0 
     LOOP 
      dbms_lob.read(vblob, byte_length, position, rawlob); 

      utl_file.put_raw(output,rawlob); 

      -- You must admit, you would have forgot to flush. 
      utl_file.fflush(output); 

      position := position + byte_length; 

      -- set the end position if less than 32000 bytes 
      temp := temp - bytelen; 
      IF temp < 32760 THEN 
       byte_length := temp; 
      END IF; 
    END IF; 
END; 
Problemi correlati