Hi, Tom.
Estoy diseñando un pequeño pkg para encapsular el codigo de generación de archivos .csv de interfaces de aplicación, pero cuando se trata de un set de datos muy grande la escritura del archivo falla, dando un error ORA-29285
Mi pregunta como puedo controlar esa falla y manejar el tamaño de la linea que trato de escribir sin afectar el rendimiento del pkg.
procedure clobTofile (p_clob clob, p_directory varchar2 := 'DIR_CSV',
p_filename varchar2 := 'file'||userenv('SESSIONID')||to_char(systimestamp,'ddmmyyyyhh24miss')||'.csv')
IS
t_clob clob := p_clob;
t_fh utl_file.file_type;
amount pls_integer := 32767;
offset integer := 1;
l_leng pls_integer := 32700;
l_fileleng number := dbms_lob.getlength(p_clob);
lc_buffer varchar2(32767);
lberr_29285 exception;
pragma EXCEPTION_INIT (lberr_29285, -29285);
begin
t_fh := utl_file.fopen( p_directory, p_filename, 'w');
begin
if ( dbms_lob.isopen(t_clob) != 1 )
then
dbms_lob.open(t_clob, 0);
end if;
--
/*
intente controlar el maximo del campo char logre romper en segmentos tomando el string 32700 como maximo,
sin embargo cuando recibo una linea o segmento que llega a medir 3213b pero no la longitud maxima controlada
falla la escritura.
*/
case when l_fileleng >= l_leng
then
--
loop
amount := instr(dbms_lob.substr( t_clob, l_leng, offset), l_endofline, -1);
exit when nvl(amount,0) = 0;
lc_buffer := dbms_lob.substr( t_clob, amount, offset);
utl_file.put_line( t_fh, lc_buffer);
offset := offset + amount;
end loop;
else
utl_file.put_line( t_fh, dbms_lob.substr( t_clob, l_fileleng, offset));
end case;
if ( dbms_lob.isopen(t_clob) = 1 ) then
dbms_lob.close(t_clob);
end if;
exception
when lberr_29285 then
dbms_output.put_line('Error :Error de escritura en el archivo archivo destino');
raise;
when others then
dbms_output.put_line('Error : '||sqlerrm);
raise;
end printout;
utl_file.fclose( t_fh );
end;
I hope I understand your question - I used google translate.
By default, UTL_FILE only allows a small line width.
Change
utl_file.fopen( p_directory, p_filename, 'w');
to
utl_file.fopen( p_directory, p_filename, 'w', 32767);
to allow a line to go up to 32k in size.