You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a CLOB parameter is greater than 32767, the procedure correctly chunks it up for the DBMS_PUT command, but it generates an error in the next iteration of the loop for going over the 32767 limit due to the DBMS_OUTPUT buffer not flushing. The DBMS_OUTPUT.new_line needs to be inside the loop to avoid generating the Oracle exception.
I believe the idea of using PUT instead of PUT_LINE was to ensure that you don't have a \n in the middle of a SELECT keyword. Moving the NEW_LINE call to the inside of the loop would undo that design philosophy.
The split will need to occur on the last \n prior to the 32767 barrier. PUT_LINE should be used instead.
Oh, that ENABLE( 1000000 ) should probably be changed to ENABLE( NULL ).
workarounds: (until fixed)
Save the CLOB to a table and then run a SELECT statement.
Use the "oddgen" plugin (another GitHub project) for SQL*Developer so that the output CLOB goes to a new worksheet.
@xendren
Any time you report a bug, please include any ORA numbers and a simple example to reproduce.
When you can, please try this loop within the output_clob body. Make sure you remove the DBMS_OUTPUT.NEW_LINE call that's at the end.
loop
exit when v_offset >dbms_lob.getlength(p_clob);
-- find "near last" occurance of '\n' - assumes Code Lines are not > 767 bytes long.
v_chunk_size :=dbms_lob.instr(p_clob,chr(10),v_offset +32000,1);
-- calculate "correct" chunk size.-- a NULL or 0 value is "invalid" - use the entire length or Max size.
v_chunk_size := least(nvl(nullif(v_chunk_size,0),99999),dbms_lob.getlength(p_clob),32767);
dbms_output.put_line(dbms_lob.substr(p_clob,v_chunk_size,v_offset));
v_offset := v_offset + v_chunk_size;
end loop;
Activity
osalvador commentedon Jun 6, 2019
Hi @xendren
Could you enumerate the steps to reproduce the issue and the sample code?
Thanks.
MikeKutz commentedon Jun 6, 2019
Verified Bug Code
DECLARE P_CLOB CLOB; BEGIN P_CLOB := lpad( 'X', 32767, 'X') || 'X'; -- P_CLOB := P_CLOB || P_CLOB ; TEPLSQL.output_clob ( P_CLOB => P_CLOB) ; END;Code to correct
I believe the idea of using
PUTinstead ofPUT_LINEwas to ensure that you don't have a\nin the middle of aSELECTkeyword. Moving theNEW_LINEcall to the inside of the loop would undo that design philosophy.The split will need to occur on the last
\nprior to the 32767 barrier.PUT_LINEshould be used instead.Oh, that
ENABLE( 1000000 )should probably be changed toENABLE( NULL ).workarounds: (until fixed)
CLOBto a table and then run a SELECT statement.CLOBgoes to a new worksheet.MikeKutz commentedon Jun 10, 2019
@xendren
Any time you report a bug, please include any ORA numbers and a simple example to reproduce.
When you can, please try this loop within the
output_clobbody. Make sure you remove theDBMS_OUTPUT.NEW_LINEcall that's at the end.loop exit when v_offset > dbms_lob.getlength(p_clob); -- find "near last" occurance of '\n' - assumes Code Lines are not > 767 bytes long. v_chunk_size := dbms_lob.instr(p_clob,chr(10),v_offset + 32000,1); -- calculate "correct" chunk size. -- a NULL or 0 value is "invalid" - use the entire length or Max size. v_chunk_size := least(nvl(nullif(v_chunk_size,0),99999),dbms_lob.getlength(p_clob),32767); dbms_output.put_line(dbms_lob.substr(p_clob,v_chunk_size,v_offset)); v_offset := v_offset + v_chunk_size; end loop;