Como capturar e manipular apenas exceções específicas do Oracle?

20

A partir deste e esta suposição eu, que não há é predefinido nomeados exceções do sistema para ORA-00955.

Como posso reescrever o seguinte para capturar apenas o erro ORA-00955?

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

BTW Existe alguma sintaxe para detectar erros fornecendo apenas os códigos de erro?

bernd_k
fonte

Respostas:

33

Você tem duas opções:


Consulte a exceção diretamente pelo número:

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; 

Outra opção é usar a EXCEPTION_INITdiretiva Pragma para vincular um número de erro conhecido do Oracle à exceção definida pelo usuário;

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 Existe alguma sintaxe para detectar erros fornecendo apenas os códigos de erro?

Sim, eu demonstrei no primeiro exemplo

Leitura adicional para variações sobre isso:

Sathyajith Bhat
fonte
11
não posso ir sem o quando os outros levantam linhas?
18111 berlim_k
@bernd_k sim, você faz isso, mas funciona como uma exceção sem
tratamento #
2
Por favor, adicione um aumento no seu WHEN OTHERS quando o sqlcodeNOT 955 =) é #
Vincent Malgrat
O OP ainda pode querer que outros erros sejam gerados. Seu bloco de exceção "como está" se comporta exatamente como um WHEN OTHERS THEN NULL. Eu acho que o OP quer algo um pouco mais preciso e sutil.
Vincent Malgrat
@VincentMalgrat Você está correto.
Sathyajith Bhat
5

Semelhante ao que Sathya já sugeriu, mas eu gosto de evitar when otherscompletamente, se possível - uma exceção não tratada geralmente é o resultado correto para as exceções que você não está lidando especificamente:

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
fonte
Isso é exatamente o que eu condensava das propostas de Sathyas.
bernd_k