PL/SQL cuenta con un modo de acceso al sistema de ficheros que abstrae al programador del medio físico. A través de la declaración de directorios virtuales (select * from ALL_DIRECTORIES) hace que sea más sencillo trabajar con recursos del sistema de ficheros. Pero al mismo tiempo dificulta el análisis de cualquier problema con el acceso a estos recursos.
Un pequeño script como el siguiente, que verifique cada una de las operaciones disponibles en PL/SQL para el acceso a un medio físico y nos informe de los errores que se produzcan en cada una de ellas, puede sernos de gran ayuda:
set serveroutput on;
DECLARE
-- Configure procedure
v_dir varchar2(255) := 'LOG_FILE_DIR';
-- Variables
f_file utl_file.file_type;
v_file varchar2(255);
v_file_dest varchar2(255);
v_file_copy varchar2(255);
v_msg_line varchar2(32767);
v_buffer varchar2(32767);
v_write_error varchar2(2048);
v_read_error varchar2(2048);
v_copy_error varchar2(2048);
v_remove_error varchar2(2048);
v_rename_error varchar2(2048);
BEGIN
-- Filename.
v_file := 'utl_test.tmp';
v_file_dest := 'utl_test_moved.tmp';
v_file_copy := 'utl_test_copied.tmp';
-- Write test.
begin
v_msg_line := 'Write test line.';
f_file := utl_file.FOPEN( v_dir, v_file, 'A', 32767 );
utl_file.PUT_LINE( f_file, v_msg_line, true );
utl_file.FCLOSE( f_file );
exception
when others then
v_write_error := sqlerrm;
end;
-- Read test.
begin
f_file := utl_file.FOPEN( v_dir, v_file, 'R', 32767 );
utl_file.GET_LINE( f_file, v_buffer, 32767 );
utl_file.FCLOSE( f_file );
exception
when others then
v_read_error := sqlerrm;
end;
-- Copy test.
begin
utl_file.FCOPY( v_dir, v_file, v_dir, v_file_copy );
exception
when others then
v_copy_error := sqlerrm;
end;
-- Remove test.
begin
utl_file.FREMOVE( v_dir, v_file );
exception
when others then
v_remove_error := sqlerrm;
end;
-- Rename test.
begin
utl_file.FRENAME( v_dir, v_file_copy, v_dir, v_file_dest );
exception
when others then
v_rename_error := sqlerrm;
end;
-- Test Result
dbms_output.put_line('UTL_FILE Test results at '||to_char(sysdate, 'dd mon yyyy hh24:mi:ss'));
dbms_output.put_line('');
dbms_output.put_line('DB_NAME.......'||sys_context('userenv','db_name'));
dbms_output.put_line('SERVER_HOST...'||sys_context('userenv','server_host'));
dbms_output.put_line('');
dbms_output.put_line('Write test....'||nvl(v_write_error, 'OK'));
dbms_output.put_line('Read test.....'||nvl(v_read_error, 'OK'));
dbms_output.put_line('Copy test.....'||nvl(v_copy_error, 'OK'));
dbms_output.put_line('Remove test...'||nvl(v_remove_error, 'OK'));
dbms_output.put_line('Rename test...'||nvl(v_rename_error, 'OK'));
-- Clean test file.
utl_file.FREMOVE( v_dir, v_file_dest );
EXCEPTION
WHEN OTHERS THEN
utl_file.FCLOSE( f_file );
dbms_output.put_line('Error utl_file_test: '||sqlerrm);
END;
Si todo es correcto, deberíamos obtener un resultado como el siguiente:
UTL_FILE Test results at 25 jun 2014 22:37:23 DB_NAME.......ora_test SERVER_HOST...vmtest Write test....OK Read test.....OK Copy test.....OK Remove test...OK Rename test...OK
