The exceptions are thrown although the file is read correctly, I understand that only the file is closed until it finds an exception. How can I change this?
CREATE OR REPLACE PROCEDURE APPS.toks_hcm_estructures (
p_errbuf OUT VARCHAR2,
p_linea OUT CLOB,
p_file_name IN VARCHAR2,
p_retcode OUT NUMBER)
AS
l_file UTL_FILE.FILE_TYPE;
v_line VARCHAR2 (32000);
my_arr v_arr1 := v_arr1 ();
v_path VARCHAR2 (100) := 'TOKS_HR_DIR_HDL';
ls_linea2 VARCHAR2 (32000);
BEGIN
l_file :=
UTL_FILE.FOPEN (v_path,
p_file_name,
'R',
32767);
BEGIN
LOOP
UTL_FILE.GET_LINE (l_file, v_line);
my_arr.EXTEND;
my_arr (my_arr.COUNT) := v_line;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
p_errbuf := 'Error al generar archivo. No se Encontraron Datos.';
p_retcode := 1;
UTL_FILE.fclose (l_file);
WHEN UTL_FILE.INVALID_FILENAME
THEN
p_errbuf := 'Error. El archivo no existe.';
p_retcode := 1;
UTL_FILE.fclose (l_file);
WHEN UTL_FILE.read_error
THEN
p_errbuf := 'Error al generar archivo. Error de Lectura.';
p_retcode := 1;
UTL_FILE.fclose (l_file);
WHEN OTHERS
THEN
p_errbuf := 'Error paquete: ' || SQLERRM;
p_retcode := 1;
UTL_FILE.fclose (l_file);
END;
FOR i IN 1 .. my_arr.COUNT
LOOP
p_linea := p_linea || CHR (10) || my_arr (i);
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
p_errbuf := 'Error paquete: ' || SQLERRM;
p_retcode := 1;
UTL_FILE.fclose (l_file);
END toks_hcm_estructures;
/
I think it was not clear what I try to do is that through the exceptions I can validate two things:
That the file exists
That the file is not empty
The exception is thrown when you read past the end of the file :
If no text was read due to end of file, the
NO_DATA_FOUND
exception is raised.
so you don't really want to treat that as an error at all. You are currently ignoring any other error though. If you're going to catch OTHERS
you should really re-throw after closing:
...
BEGIN
l_file := UTL_FILE.FOPEN(v_path, p_file_name, 'R',32767);
BEGIN
LOOP
UTL_FILE.GET_LINE (v_file, v_line);
my_arr.EXTEND;
my_arr (my_arr.COUNT) := v_line;
END LOOP;
EXCEPTION
WHEN no_data_found THEN
--p_errbuf := 'Error de lectura. No se Encontraron Datos.';
--p_retcode := 1;
UTL_FILE.FCLOSE (v_file);
WHEN OTHERS THEN
UTL_FILE.FCLOSE (v_file);
RAISE; -- re-throw exception so it is reported
END;
UTL_FILE.FCLOSE (v_file);
...
or (after your edit) if every exception handler sets a message but doesn't return early - perhaps they should? - you only need the single close after the end of that sub-block. I added that because your original code closes the file on error, but not on success.
The file being empty is not an error condition as far as Oracle is concerned, so you won't get an exception just for that. But if the file is empty then my_arr.COUNT
will still be zero after the loop, so you can test for that:
...
END;
IF my_arr.COUNT = 0 THEN
p_errbuf := 'Error al generar archivo. No se Encontraron Datos.';
p_retcode := 1;
END IF;
FOR i IN 1..my_arr.COUNT LOOP
...
after the loop (either, really; the second loop does nothing in that scenario anyway). The file is already closed by now.
Or if you prefer, keep your original code but check the count when you see the exception:
...
BEGIN
l_file := UTL_FILE.FOPEN(v_path, p_file_name, 'R',32767);
BEGIN
LOOP
UTL_FILE.GET_LINE(l_file, v_line);
my_arr.EXTEND;
my_arr(my_arr.COUNT) := v_line;
END LOOP;
EXCEPTION
WHEN no_data_found THEN
IF arr.COUNT = 0 THEN
p_errbuf := 'Error al generar archivo. No se Encontraron Datos.';
p_retcode := 1;
END IF;
UTL_FILE.FCLOSE (v_file);
WHEN UTL_FILE.INVALID_FILENAME THEN
...
If the count is greater than zero when it's thrown then the file was not empty.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.