Как закрыть чтение файла

Исключения кидаются хотя файл читается корректно, я так понимаю только файл закрывается пока не найдет исключение. Как я могу это изменить?

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. Что файл не пустой

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
406
1

Ответы 1

Выдается исключение когда вы читаете дальше конца файла:

If no text was read due to end of file, the NO_DATA_FOUND exception is raised.

так что вы вообще не хотите рассматривать это как ошибку. Однако в настоящее время вы игнорируете любую другую ошибку. Если вы собираетесь поймать 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
...

Если счетчик больше нуля, когда он выброшен, файл не был пустым.

Извините, Алекс, мне кажется, было непонятно, что я пытаюсь сделать. Я обновил пост немного более подробно и с процедурой, которую я сейчас использую.

Lorenzo Lamas Moo 01.03.2019 01:21

Если файл не существует, вы получите ошибку файла, а не no_data_found — это чтение после конца существующего файла. И если файл пуст, то после этого цикла my_arr.COUNT будет равен нулю, поэтому вы можете проверить это явно и установить сообщение об ошибке.

Alex Poole 01.03.2019 01:21

и могу ли я ввести выходную переменную, когда my_arr.COUNT будет равен нулю?? Я пытаюсь сделать это, потому что мне нужны ошибки в выходных переменных, которые я затем буду использовать в другом инструменте, в котором я должен показывать статус чтения, и если статус был неполным, это показывает ошибку. Я не очень разбираюсь в PL/SQL, поэтому мне не все так ясно.

Lorenzo Lamas Moo 01.03.2019 01:35

Да, это то, что я показал в своем редактировании. Последний подход может показаться вам самым простым - с IF внутри вашего существующего обработчика исключений....

Alex Poole 01.03.2019 01:39

Другие вопросы по теме