Блок << SQL_ERROR >> - PullRequest
       24

Блок << SQL_ERROR >>

0 голосов
/ 13 октября 2009

В наших хранимых процедурах к концу мы имеем следующий код.

  <<SQL_ERROR>>
  V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252);

  DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE');

  DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' ||
                       V_SYS_ERROR_MSG);

у нас есть операторы вроде следующего, которые вызывают блок ошибки.

  IF V_SYS_ERROR <> 0 THEN
    GOTO SQL_ERROR;

операторы вывода СУБД приходят, даже если ошибки нет. Как мы можем избежать этого?

Ответы [ 3 ]

2 голосов
/ 14 октября 2009

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

BEGIN
  IF V_SYS_ERROR <> 0 THEN
    GOTO SQL_ERROR;
  END IF;

  GOTO PROC_END;

  <<SQL_ERROR>>
    V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252);

    DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE');

    DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' ||
                         V_SYS_ERROR_MSG);

  <<PROC_END>>
  NULL;
END;

Конечно, это по-прежнему требует изменения кода, так что если вы делаете это, почему бы не сделать это должным образом? т.е. * +1008 *

DECLARE
  SQL_ERROR EXCEPTION;
BEGIN
  IF V_SYS_ERROR <> 0 THEN
    RAISE SQL_ERROR;
  END IF;

EXCEPTION

  WHEN SQL_ERROR THEN
    V_SYS_ERROR_MSG := SUBSTR(SQLERRM, 1, 252);

    DBMS_OUTPUT.PUT_LINE('ERROR IN EXECUTION IN PROCEDURE');

    DBMS_OUTPUT.PUT_LINE('THE ERROR CODE IS ' || V_SYS_ERROR || '- ' ||
                         V_SYS_ERROR_MSG);
    RAISE;

END;

Кстати, DBMS_OUTPUT.PUT_LINE не подходит для вывода сообщений об ошибках в производственной прикладной системе. Используйте его только для отладки во время разработки.

2 голосов
/ 13 октября 2009

вам следует избегать GOTO-выражений, они грязные, как вы заметили. PL / SQL поставляется с обработкой ошибок, вы должны использовать синтаксис EXCEPTION для обработки ошибок:

BEGIN
   <code goes here>
EXCEPTION
   WHEN <exception> THEN
      <deal_with_it>
   WHEN OTHERS THEN
      <log_error>
      RAISE;
END;
1 голос
/ 13 октября 2009

Не думаю, что вы получите желаемый результат без использования обработчика исключений. Из руководства пользователя PL / SQL:

SQLERRM без аргументов полезен только в обработчике исключений. за пределами обработчик, SQLERRM без аргументов всегда возвращает нормальный, успешный сообщение о завершении.

Итак, во-первых, возможно, что произошла ошибка, но вы видите сообщение «нормальное, успешное завершение», потому что это то, что SQLERRM всегда возвращает в этом контексте.

Если предположить, что это не так, похоже, что вы просто позволяете элементу управления перетекать из "обычного" кода в "обработчик ошибок". Если обработчик ошибок находится в самом конце процедуры, тогда простым решением было бы добавить инструкцию RETURN непосредственно перед меткой <>.

Лучшим решением было бы переместить код обработчика ошибок в отдельную процедуру и вызвать эту процедуру вместо использования GOTO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...