[英]How to close the reading of a file
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.如果由于文件结尾而未读取任何文本,则会引发
NO_DATA_FOUND
异常。
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: 如果您要赶上
OTHERS
,则应该在结束比赛后重新抛出:
...
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. 就Oracle而言,文件为空不是错误条件,因此您不会因此而获得异常。 But if the file is empty then
my_arr.COUNT
will still be zero after the loop, so you can test for that: 但是,如果文件为空,则循环后
my_arr.COUNT
仍为零,因此您可以对此进行测试:
...
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. 如果计数在抛出时大于零,则文件不为空。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.