Einen CLOB gesplittet in SQL*Plus ausgeben um einen - ORA-22835: Buffer too small for CLOB - zu vermeiden
Das Problem:
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 4509, maximum: 4000)
Bei der Auswertung des Error Trigger Logging ( siehe ⇒ Erstellen eines Protokolls zur Überwachung von fehlerhaften SQL Statements in der Datenbank - AFTER SERVERERROR Trigger verwenden ) kommt es beim einfachen Selektieren der Log Tabelle zu einem ORA-22835: Buffer too small.
Mehr als 4k an Zeichen kann in SQL*Plus aus einer CLOB Spalte nicht direkt gelesen werden, ein Setzen des Buffers für Long/RAW Daten mit „set buffer 65000“ hilft hier leider auch nicht.
Eine Lösung kann sein den CLOB in 4K Blöcke mit dbms_lob.substr (clob, amount, position ) aufzusplieten und die mehren Spalten auszugeben.
Die Lösung:
CLOB in einzelne „Chunks“ aufteilen:
WITH ErrorLog AS ( SELECT stmt , log_date , LOG_USR , ERR_NR , substr(ERR_MSG,1,300) mesg , dbms_lob.getlength(STMT) len FROM SYSTEM.ora_errors WHERE nvl(log_usr,'n/a') NOT IN ('SYS','SYSMAN','DBSNMP') ) SELECT COUNT (*) AS anzahl , to_char(MIN(log_date),'dd.mm.yyyy hh24:mi') first_log_entry , to_char(MAX(log_date),'dd.mm.yyyy hh24:mi') last_log_entry , LOG_USR , ERR_NR , mesg , dbms_lob.substr(stmt,4000,1) sql_part1 , CASE WHEN len > 4000 THEN dbms_lob.substr(stmt,4000,4001) END sql_part2 , CASE WHEN len > 8000 THEN dbms_lob.substr(stmt,4000,8001) END sql_part3 , CASE WHEN len > 12000 THEN dbms_lob.substr(stmt,4000,12001) END sql_part4 , CASE WHEN len > 16000 THEN dbms_lob.substr(stmt,4000,165001) END sql_part5 FROM ErrorLog GROUP BY LOG_USR , ERR_NR , mesg , dbms_lob.substr(stmt,4000,1) , CASE WHEN len > 4000 THEN dbms_lob.substr(stmt,4000,4001) END , CASE WHEN len > 8000 THEN dbms_lob.substr(stmt,4000,8001) END , CASE WHEN len > 12000 THEN dbms_lob.substr(stmt,4000,12001) END , CASE WHEN len > 16000 THEN dbms_lob.substr(stmt,4000,165001) END ORDER BY 1 /