Comment intercepter et gérer uniquement des exceptions Oracle spécifiques?

20

D'après cela et cela, je suppose qu'il n'y a aucune exception de système nommé prédéfinie pour ORA-00955.

Comment puis-je réécrire ce qui suit pour ne détecter que l'erreur ORA-00955?

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

BTW Existe-t-il une syntaxe pour détecter les erreurs en fournissant simplement les codes d'erreur?

bernd_k
la source

Réponses:

33

Vous avez deux options:


Reportez-vous directement à l'exception par son numéro:

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; 

Une autre option consiste à utiliser la EXCEPTION_INITdirective Pragma pour lier un numéro d'erreur Oracle connu à une exception définie par l'utilisateur;

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-t-il une syntaxe pour détecter les erreurs en fournissant simplement les codes d'erreur?

Oui, je l'ai démontré dans le premier exemple

Pour en savoir plus sur les variations à ce sujet:

Sathyajith Bhat
la source
1
ne puis-je pas simplement me passer de quand les autres élèvent des lignes?
bernd_k
@bernd_k oui vous le faites, cela va cependant comme une exception non
gérée
2
Veuillez ajouter une augmentation dans votre QUAND D'AUTRES quand ce sqlcoden'est PAS 955 =)
Vincent Malgrat
L'OP peut toujours souhaiter que d'autres erreurs soient déclenchées. Votre bloc d'exception "tel quel" se comporte exactement comme QUAND D'AUTRES PUIS NUL. Je pense que l'OP veut quelque chose d'un peu plus précis et subtil.
Vincent Malgrat
@VincentMalgrat Vous avez raison.
Sathyajith Bhat
5

Semblable à ce que Sathya a déjà suggéré, mais j'aime éviter when otherscomplètement si possible - une exception non gérée est généralement le résultat correct pour les exceptions que vous ne gérez pas spécifiquement:

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
la source
C'est exactement ce que j'ai condensé des propositions de Sathyas moi-même.
bernd_k