2016-05-17 2 views
2

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

В моем пакете есть процедуры и функции, а в случае, скажем, исключения NO_DATA_FOUND Я хочу сделать то же самое во всех своих процедурах и функциях.

Так что мой вопрос: могу ли я написать

WHEN NO_DATA_FOUND THEN 

только один раз и использовать ту же линию для NO_DATA_FOUND исключения во всех мои процедурах/функциях, или я должен написать, что обработчик исключений в каждой процедуре/функции ,

ответ

4

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

Общее правило, которое я применяю, это: «если у вас нет чего-то конкретного и полезного в ответ на исключение, не поймите его».

Ожидается, что в данной ситуации ожидается NO_DATA_FOUND, и вы можете игнорировать его и/или принимать значение по умолчанию для данных, тогда вы захотите его поймать и обработать (и обработчик на уровне пакетов не будет помогите, потому что ваша обработка будет зависящей от ситуации). Во всех остальных случаях вы не хотите поймать NO_DATA_FOUND - он представляет собой истинное исключение: что-то, чего не должно было быть, что-то вне ваших предположений о дизайне. Пусть они распространяются до верхнего уровня, которые могут их регистрировать и/или сообщать о них клиенту.

Но, возможно, вы получили бы более качественные ответы, если бы объяснили, что вам нужно, чтобы обработчик исключений на уровне пакета.

+0

я согласен с вами, таким образом, и Allready имею Querry исключения уровня, которые есть по уважительным причинам, присвоить значение переменных и так далее. Исключения на уровне пакета были предназначены только для целей ведения журнала, это сложно объяснить, но я не могу регистрировать исключение на более высоком уровне, поэтому мне нужно сделать это внутри этого пакета. спасибо за Ваш ответ – BeRightBack

5

Нет, вы не можете обрабатывать исключение глобально по всем процедурам/функциям в пакете.

The exception handler documentation говорит:

обработчик исключений обрабатывает поднятое исключение. Обработчики исключений появляются в части обработки исключений из анонимных блоков, подпрограмм, триггеров и пакетов.

Звучит так, как вы можете; но ссылка «пакеты» есть имеет в виду раздел инициализации в create package body statement:

enter image description here

Но что раздел «Инициализация переменных и делает любые другие одноразовые действия установки», и выполняется один раз за сеанс, когда сначала запускается функция или процедура в пакете. Его обработчик исключений не делает ничего другого.

Если вы действительно хотите подобное поведение, вы можете поместить его в свою собственную (возможно, частную) процедуру и вызвать ее из обработчика исключений для каждой процедуры/функции. Это может сэкономить немного набрав, но, вероятно, замаскирует то, что на самом деле происходит, если вы пытаетесь зарегистрировать ошибки, скажем. Вероятно, будет проще и лучше иметь специальную обработку исключений, даже если это вызывает некоторое повторение.

4

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

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

PROCEDURE p1 
AS 
    ... 
BEGIN 
    BEGIN 
    SELECT col1 
     INTO l_var1 
     FROM some_table 
    WHERE <<something>> 
    EXCEPTION 
    WHEN no_data_found 
    THEN 
     l_var1 := null; 
    END; 

    <<do something>> 

    BEGIN 
    SELECT col2 
     INTO l_var2 
     FROM some_table2 
    WHERE <<something>> 
    EXCEPTION 
    WHEN no_data_found 
    THEN 
     raise_application_error(-20001, 'Error, cannot find a row in some_table2'); 
    END; 

    ... 
END; 
Смежные вопросы