¿Cómo atrapar y manejar solo excepciones específicas de Oracle?

20

De esto y de esto , supongo, que no hay excepciones de sistema con nombre predefinidas para ORA-00955.

¿Cómo puedo reescribir lo siguiente para detectar solo el error ORA-00955?

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

Por cierto, ¿hay alguna sintaxis para detectar errores simplemente proporcionando los códigos de error?

bernd_k
fuente

Respuestas:

33

Tienes dos opciones:


Consulte la excepción directamente por 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; 

Otra opción es usar la EXCEPTION_INITdirectiva Pragma para vincular un número de error de Oracle conocido a la excepción definida por el usuario;

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; 

Por cierto, ¿hay alguna sintaxis para detectar errores simplemente proporcionando los códigos de error?

Sí, lo he demostrado en el primer ejemplo.

Lecturas adicionales para variaciones sobre esto:

Sathyajith Bhat
fuente
1
¿No puedo ir sin ir cuando los otros levantan líneas?
bernd_k
@bernd_k sí, lo haces, sin embargo, es una excepción no controlada
Sathyajith Bhat
2
Agregue un aumento en su CUANDO OTROS cuando sqlcodeNO sea 955 =)
Vincent Malgrat
El OP aún puede querer que se generen otros errores. Su bloque de excepción "tal cual" se comporta exactamente como CUANDO OTROS ENTONCES NULO. Creo que el OP quiere algo un poco más preciso y sutil.
Vincent Malgrat
@VincentMalgrat Estás en lo correcto.
Sathyajith Bhat
5

Similar a lo que Sathya ya ha sugerido, pero me gusta evitarlo por when otherscompleto si es posible: una excepción no controlada suele ser el resultado correcto para excepciones que no está manejando específicamente:

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
fuente
Eso es exactamente lo que condensé de las propuestas de Sathyas.
bernd_k