Это плохая практика использовать глобальные исключения в PL / SQL? - PullRequest
2 голосов
/ 23 декабря 2009

Плохо ли делать то, что делает код ниже? Случатся ли со мной плохие вещи, когда я это напишу?

Редактировать: это всего лишь пример. Я бы не использовал dbms_output для каких-либо реальных сообщений об ошибках.

CREATE OR REPLACE PACKAGE my_package
AS
PROCEDURE master;
END;
/

CREATE OR REPLACE PACKAGE BODY my_package
AS

my_global_interrupt EXCEPTION;


PROCEDURE my_private_procedure
IS
BEGIN
  -- in case some flag is raised, raise exception to stop process and prepare for resume
  RAISE my_global_interrupt;
END;

PROCEDURE master
IS
BEGIN
  my_private_procedure;
EXCEPTION
  WHEN my_global_interrupt THEN 
    dbms_output.put_line('global interrupt, ');
    -- prepare to resume
END;

END;
/

Ответы [ 2 ]

8 голосов
/ 23 декабря 2009

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

create or replace package body my_pkg 
as
    my_x1 exception;
    my_x2 exception;
    my_x3 exception;
    PROCEDURE p1 is
    begin
        ...
    exception
        when no_data_found then raise my_x1;
    end p1;
    PROCEDURE p2 is
    begin
        ...
    exception
        when no_data_found then raise my_x2;
    end p2;
    PROCEDURE p3 is
    begin
        ...
    exception
        when no_data_found then raise my_x3;
    end p3;
    PROCEDURE master is
    begin
        p1;
        p2;
        p3;
    exception
        when my_x1 then do_this;
        when my_x2 then do_that;
        when my_x3 then do_the_other;
    end master;
end my_pkg;
/

Использование глобально объявленных исключений облегчает обработку исключений в процедуре master.

Кроме того, имейте в виду, что иногда мы хотим распространить исключение за пределы пакета, например, программу, которая вызывает нашу публично объявленную процедуру. Мы можем сделать это, определив наши исключения в спецификации пакета. Это означает, что другие процедуры могут ссылаться на них ...

SQL> begin
  2      my_pkg.master;
  3  exception
  4      when my_pkg.my_public_x1
  5          then dbms_output.put_line('oh no!');
  6  end;
  7  /
oh no!

PL/SQL procedure successfully completed.

SQL>

Мы также можем связать такие исключения с конкретными номерами ошибок, чтобы они были распознаваемыми, даже если вызывающая процедура явно их не обрабатывает.

SQL> exec my_pkg.master
BEGIN my_pkg.master; END;

*
ERROR at line 1:
ORA-20999:
ORA-06512: at "APC.MY_PKG", line 32
ORA-06512: at line 1


SQL>

Это (немного) более полезно, чем общая ошибка ORA-06510.

2 голосов
/ 23 декабря 2009

Выглядит достаточно разумно для меня, при условии, что вы счастливы, что после условия прерывания можно продолжить обработку. Если вы собираетесь каким-то образом регистрировать прерывание, возможно, лучше вставить строку в таблицу журналов с помощью автономной транзакции. Вы не увидите ничего из DBMS_OUTPUT, пока не завершится вся процедура. Тогда вы увидите все DBMS_OUTPUT одновременно.

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