Jak wychwytywać i obsługiwać tylko określone wyjątki Oracle?

20

Z tego i tego, jak sądzę, nie ma predefiniowanych Nazwanych Systemowych Wyjątków dla ORA-00955.

Jak mogę przepisać poniższe, aby wychwycić tylko błąd ORA-00955?

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

BTW Czy istnieje jakaś składnia do wychwytywania błędów po prostu poprzez podanie kodów błędów?

bernd_k
źródło

Odpowiedzi:

33

Masz dwie opcje:


Odwołaj się do wyjątku bezpośrednio według numeru:

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; 

Inną opcją jest użycie EXCEPTION_INITdyrektywy Pragma do powiązania znanego numeru błędu Oracle z wyjątkiem zdefiniowanym przez użytkownika;

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; 

BTW Czy istnieje jakaś składnia do wychwytywania błędów po prostu poprzez podanie kodów błędów?

Tak, zademonstrowałem to w pierwszym przykładzie

Więcej informacji na temat wariantów tego:

Sathyajith Bhat
źródło
1
czy nie mogę po prostu przejść bez tego, kiedy inni podnoszą linie?
bernd_k,
@bernd_k tak, robisz to, jest to jednak nieobsługiwany wyjątek
Sathyajith Bhat,
2
Proszę dodać podwyżkę w KIEDY INNY, gdy sqlcodeNIE jest 955 =)
Vincent Malgrat
OP może nadal chcieć zgłaszać inne błędy. Twój blok wyjątków „tak jak jest” zachowuje się dokładnie tak, JAK INNY NIŻ NULL. Myślę, że OP chce czegoś bardziej precyzyjnego i subtelnego.
Vincent Malgrat,
@VincentMalgrat Masz rację.
Sathyajith Bhat,
5

Podobne do tego, co już zasugerował Sathya, ale lubię when otherscałkowicie unikać, jeśli to możliwe - nieobsługiwany wyjątek jest zwykle prawidłowym wynikiem dla wyjątków, z którymi konkretnie nie postępujesz:

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
*/
Jack Douglas
źródło
Właśnie to streściłem z propozycji Sathyasa.
bernd_k,