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