如何关闭文件的读取

问题描述 投票:0回答:1

尽管文件被正确读取,但抛出异常,我知道只有文件才会被关闭,直到它找到异常。我怎么能改变这个?

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;
/

我认为不清楚我试图做的是通过例外我可以验证两件事:

  1. 该文件存在
  2. 该文件不为空
oracle stored-procedures plsql exception-handling
1个回答
0
投票

抛出when you read past the end of the file的例外情况:

如果由于文件结尾没有读取文本,则会引发NO_DATA_FOUND异常。

所以你根本不想把它视为一个错误。您目前正在忽略任何其他错误。如果你要赶上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);
...

或者(在编辑之后)如果每个异常处理程序都设置了一条消息但是没有提前返回 - 也许它们应该? - 您只需要在该子块结束后关闭单个。我补充说,因为您的原始代码在出错时关闭文件,但不是成功。

就Oracle而言,文件为空不是错误条件,因此您不会为此获得异常。但是如果文件为空,那么循环后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
...

循环之后(或者,真的;无论如何,第二个循环在该场景中什么都不做)。该文件现在已经关闭。

或者,如果您愿意,请保留原始代码,但在看到异常时检查计数:

...
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
...

如果计数在抛出时大于零,则文件不为空。

© www.soinside.com 2019 - 2024. All rights reserved.