Не удалось поднять сообщение об ошибке приложения

Для целей отладки мне нужно поднять сообщение уровня приложения на основе данного флага. Вот код исключения

  EXCEPTION
    WHEN dml_errors THEN
      l_errors := SQL%BULK_EXCEPTIONS.COUNT;
      S_Publish('I', 'Number of statements that failed: ' || l_errors);
      FOR i IN 1..l_errors LOOP
         S_Publish('I', 'Error #' || TO_CHAR(i) || ' occurred during '|| 'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
         S_Publish('I', 'Error message is ' || SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
         S_Publish('I', 'Failing Record ID is ' || sap_tbl_ins(SQL%BULK_EXCEPTIONS(i).ERROR_INDEX).DEVICE_PIN);
      END LOOP;
      IF g_app_error_flag THEN
        raise_application_error(-20707, 'Fatal Error: Replication script exceptions', TRUE);
      END IF;

    WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE('Error on record:' || l_zzman);
      S_Publish('I', 'SAP_EQUI Update: Failure processing record ' || l_zzman);
      S_Publish ('F');
      IF g_app_error_flag THEN
        raise_application_error(-20708, 'Fatal Error: Replication script exceptions', TRUE);
      END IF;

теперь, учитывая этот код, raise_application_error должен подниматься всякий раз, когда ** g_app_error_flag истинно. Тем не менее, во всех случаях (я имею в виду среду тестирования, в которой я намеренно отказываюсь от сценария, добавляя некоторое ограничение в таблицу), все, что я вижу, это ошибка DML, т. Е.

ORA-01403: no data found 
ORA-06512: at "DBNAME.PRODUCT_COPY_PACKAGE", line 1808 
ORA-24381: error(s) in array DML 
ORA-06512: at "DBNAME.PRODUCT_COPY_PACKAGE", line 84 
ORA-06512: at line 3 

могли бы вы, ребята, сказать, что происходит?

P.S:

вот определение для S_Publish. В S_Publish нет «рейза».

  PROCEDURE S_Publish (i_type IN VARCHAR2, 
                         i_msg IN VARCHAR2 DEFAULT NULL) IS
  BEGIN

    CASE

       WHEN i_type = 'G' THEN
         IF g_debug_flag
         THEN
           INSERT INTO logtable (tstamp,line) values (SYSDATE, i_msg);
           COMMIT;
           g_counter := 0;
         END IF;

       WHEN i_type = 'F' THEN
         g_err_code  := SQLCODE;
         g_err_msg   := TO_CHAR(g_err_code)||' '||SUBSTR(SQLERRM, 1, 100);
         INSERT INTO logtable (tstamp,line) values (SYSDATE, g_err_msg);
         COMMIT;

       WHEN i_type = 'I' THEN
         INSERT INTO logtable (tstamp,line) values (SYSDATE, i_msg);
         COMMIT;
         g_counter := 0;

    END CASE;


  END S_Publish;

После небольшой отладки это то, что я выяснил до сих пор. Я не знаю, что за ним стоит

Таким образом, проблема заключается в том, что программа выходит не раньше, чем заканчивает печатать ошибки, то есть FOR i IN 1..l_errors LOOP . Программа выходит из END LOOP . Почему что-то после этого не выполняется?

3
Согласитесь, но из-за причин производительности были введены флаги для уменьшения отладочных сообщений в рабочей среде. Истинный g_app_err_flag отправляется как значение TRUE при вызове сценария. В скрипте нет logic , который устанавливает g_app_error_flag true/false.
добавлено автор x.509, источник
Как вы знаете, что для параметра g_app_error_flag установлено значение TRUE? И функционально, какой смысл он делает, чтобы проверить флаг ошибки в обработчике исключений? Конечно, тот факт, что вы находитесь в обработчике исключений, означает, что приложение столкнулось с ошибкой. Наличие дополнительного логического флага, похоже, не добавляет никакой информации и просто создает потенциал для дополнительных ошибок.
добавлено автор Justin Cave, источник

3 ответы

Таким образом, проблема была в S_Publish . таблица ссылается на i.e. sap_tbl_ins на 0 . SQL% BULK_EXCEPTIONS (i) .ERROR_INDEX - это, в основном, номер итерации, когда это не удалось. Таким образом, ссылаясь на индекс, основанный на 0, с номером поднимает исключение «array out of bound». Я просто вычислил это и изменил формулу на

S_Publish('I', 'Failing Record ID is ' || sap_tbl_ins((SQL%BULK_EXCEPTIONS(i).ERROR_INDEX)-1).DEVICE_PIN);

и его рабочий штраф.

2
добавлено

Хорошо, вопросы:

1) Что такое код в строке 1808 в PRODUCT_COPY_PKG. Здесь возникает первая ошибка.

2) Есть ли вставки в журнальный стол? (то есть - этот блок исключений действительно выполняется?)

3) Является ли этот вывод стека ошибок из ваших операторов dbms_output? Или, что дамп стека из Oracle во время выполнения?

Заметка стиля: Я надеюсь, что S_PUBLISH определяется с помощью PRAGMA AUTONOMOUS_TRANSACTION, иначе ваш COMMIT может совершать частично завершенную транзакцию, если ваш код был посреди дела, когда он выходил из системы.

0
добавлено

Поскольку мы не видим весь код, мы должны полагаться на вас, что, когда вы выполняете неудачу сценария намеренно, добавляя какое-то ограничение в таблицу, этот блок исключений, который вы опубликовали, является активным. Поэтому, если этот блок вступает в действие, причина, по которой вы не видите свой «raise_application_error (-20707, .....» или второй с -20708, может заключаться в том, что процедура «S_Publish» бросает исключение , Которые не будут пойманы в том же блоке исключений, где они выполняются, если вы не окружите их дополнительным. Чтобы проверить эту теорию, попробуйте временно удалить вызовы и посмотреть, есть ли у вас возникшая ошибка.

0
добавлено
ju8st обновил исходный тест с помощью определения S_PUBLISH . исключение throw не существует в S_PUBLISH .
добавлено автор x.509, источник
строка 1808 вставляет данные в таблицу с 3 значениями, например col1, col2, col3. Однако таблица имеет 4 столбца и ограничение not null на col4. Из-за этого исключение исключается. Вопрос в том, что это исключенное исключение, оно попало в исключение , когда другие & , но ошибка уровня приложения не поднимается оттуда, хотя я поднимаю его эксплицитно оттуда.
добавлено автор x.509, источник
Таким образом, проблема заключается в том, что программа выходит не раньше, чем заканчивает печатать ошибки, то есть FOR i IN 1..l_errors LOOP . Программа выходит из END LOOP . Почему что-то после этого не выполняется?
добавлено автор x.509, источник
он не должен явно бросать исключение. при запуске может произойти исключение. но поскольку вы отправили свой код, я не думаю, что он выбрасывает исключение no_data_found, поскольку я не вижу в нем операторов select (и я полагаю, что триггеры не запускаются после вставки в таблицу журналов, у которых есть выбор, который может завершиться неудачей). вы можете показать больше кода (возможно, используя pastebin.com ). особенно «DBNAME.PRODUCT_COPY_PACKAGE», строка 1808 », поскольку исключение выбрано там. Ваш обработчик Exception обертывает место, где происходит исключение?
добавлено автор A.J., источник
последнее: замените «raise_application_error» на некоторую строку DBMS_OUTPUT.PUT_LINE по вашему выбору. видите ли вы, что это запечатлелось?
добавлено автор A.J., источник
SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)

Oracle RU
Oracle RU
303 участник(ов)

Русскоязычная группа по Oracle. — Архитектура СУБД — PL/SQL — Оптимизация — Администрирование — Вакансии Oracle (указать инфу по вилке ЗП и удалёнке) Приглашайте коллег :-) Запрещены: личные оскорбления, обсуждения оффтопик вопросов политики и религии