Как ловить и обрабатывать только определенные исключения Oracle?


20

Из этого и этого я предполагаю, что нет предопределенных именованных системных исключений для ORA-00955.

Как я могу переписать следующее, чтобы поймать только ошибку ORA-00955?

begin
      EXECUTE IMMEDIATE 'CREATE SEQUENCE S_TEST START WITH 1 INCREMENT BY 1';
exception when OTHERS then
    Null;
end;

Кстати, есть ли какой-нибудь синтаксис для перехвата ошибок, просто предоставляя коды ошибок?

Ответы:


33

У вас есть два варианта:


Обращайтесь к исключению напрямую по номеру:

BEGIN
    EXECUTE IMMEDIATE 'CREATE SEQUENCE S_TEST START WITH 1 INCREMENT BY 1';
EXCEPTION
    WHEN OTHERS THEN
      IF SQLCODE = -955 THEN
        NULL; -- suppresses ORA-00955 exception
      ELSE
         RAISE;
      END IF;
END; 

Другой вариант - использовать EXCEPTION_INITдирективу Pragma, чтобы связать известный номер ошибки Oracle с пользовательским исключением;

DECLARE
   name_in_use exception; --declare a user defined exception
   pragma exception_init( name_in_use, -955 ); --bind the error code to the above 
BEGIN
    EXECUTE IMMEDIATE 'CREATE SEQUENCE S_TEST START WITH 1 INCREMENT BY 1';
EXCEPTION
    when name_in_use then
       null; --suppress ORA-00955 exception
END; 

Кстати, есть ли какой-нибудь синтаксис для перехвата ошибок, просто предоставляя коды ошибок?

Да, я продемонстрировал это в первом примере

Дальнейшее чтение для вариаций этого:


1
я не могу пойти просто без того, когда другие поднимают линии?
bernd_k

@bernd_k да, вы делаете это, однако это
необратимое

2
Пожалуйста, добавьте рейз в свои КОГДА ДРУГИЕ, когда sqlcodeНЕ 955 =)
Винсент Малграт

ОП может по-прежнему хотеть, чтобы возникли другие ошибки. Ваш Исключительный блок "как есть" ведет себя точно так же, КОГДА ДРУГОЙ, ЧЕМ НУЛЬ. Я думаю, что ОП хочет что-то более точное и тонкое.
Винсент Малграт

@VincentMalgrat Вы правы.
Сатьяджит Бхат

5

Подобно тому, что Сатья уже предлагал, но я хотел бы when othersполностью избежать, если это возможно - необработанное исключение обычно является правильным результатом для исключений, которые вы специально не обрабатываете:

create sequence foo;
/*
sequence FOO created.
*/
declare
  name_is_already_used_955 exception;
  pragma exception_init(name_is_already_used_955,-955);
begin
  execute immediate 'create sequence foo';
exception when name_is_already_used_955 then null;
end;
/
/*
anonymous block completed
*/

Это именно то, что я сам собрал из предложений Сатья.
bernd_k
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.