Traitement des anomalies (erreurs d'exécution)
Vous pouvez gérer les exceptions qui se produisent lors de l'exécution avec du code PL/SQL.
Voir aussi : Informations de référence sur le langage PL/SQL pour Oracle Database pour plus d'informations sur le traitement des erreurs PL/SQL.
À propos des programmes de traitement des exceptions et des exceptions
Lorsqu'une erreur d'exécution se produit dans le code PL/SQL, une exception est générée. Si le sous-programme (ou bloc) dans lequel l'exception est générée comporte une partie de traitement des exceptions, contrôlez les transferts vers ce sous-programme; sinon, l'exécution s'arrête.
Les erreurs d'exécution peuvent provenir d'erreurs de conception, d'erreurs de codage, de défaillances matérielles et de nombreuses autres sources.
Oracle Database comporte de nombreuses exceptions prédéfinies, qu'il déclenche automatiquement lorsqu'un programme enfreint les règles de base de données ou dépasse les limites dépendantes du système. Par exemple, si une instruction SELECT INTO ne renvoie aucune ligne, Oracle Database génère l'exception prédéfinie NO_DATA_FOUND. Pour obtenir un sommaire des exceptions PL/SQL prédéfinies, voir Informations de référence sur le langage PL/SQL pour Oracle Database.
PL/SQL vous permet de définir (déclarer) vos propres exceptions. Une déclaration d'exception comporte la syntaxe suivante :
exception_name EXCEPTION;
Contrairement à une exception prédéfinie, une exception définie par l'utilisateur doit être déclenchée explicitement, à l'aide de l'énoncé RAISE ou de la procédure DBMS_STANDARD.RAISE_APPLICATION_ERROR. Par exemple :
IF condition THEN RAISE exception_name;
Pour plus d'informations sur la procédure DBMS_STANDARD.RAISE_APPLICATION_ERROR, voir Informations de référence sur le langage PL/SQL pour Oracle Database.
La partie de traitement des exceptions d'un sous-programme contient un ou plusieurs gestionnaires d'exceptions. Un programme de traitement d'exceptions a la syntaxe suivante :
WHEN { exception_name [ OR exception_name ]... | OTHERS } THEN
statement; [ statement; ]...
("À propos de la structure d'un sous-programme " indique où placer la partie de traitement des exceptions d'un sous-programme.)
Un gestionnaire d'exceptions WHEN OTHERS traite les erreurs d'exécution inattendues. S'il est utilisé, il doit être le dernier. Par exemple :
EXCEPTION
WHEN exception_1 THEN
statement; [ statement; ]...
WHEN exception_2 OR exception_3 THEN
statement; [ statement; ]...
WHEN OTHERS THEN
statement; [ statement; ]...
RAISE; -- Reraise the exception (very important).
END;
Une alternative au gestionnaire d'exceptions WHEN OTHERS est le pragma EXCEPTION_INIT, qui associe un nom d'exception défini par l'utilisateur à un numéro d'erreur Oracle Database.
Voir aussi :
-
Informations de référence sur le langage PL/SQL pour Oracle Database pour plus d'informations sur la syntaxe de déclaration d'exception
-
Informations de référence sur le langage PL/SQL pour Oracle Database pour plus d'informations sur la syntaxe du programme de traitement des exceptions
-
Informations de référence sur le langage PL/SQL pour Oracle Database pour plus d'informations sur le pragma EXCEPTION_INIT
Quand utiliser les gestionnaires d'exceptions
Utilisez des gestionnaires d'exceptions uniquement dans les cas suivants.
-
Vous attendez une exception et souhaitez la gérer.
Par exemple, vous prévoyez qu'une instruction SELECT INTO finira par ne renvoyer aucune ligne, ce qui entraînera la génération par Oracle Database de l'exception prédéfinie NO_DATA_FOUND. Vous voulez que votre sous-programme ou bloc traite cette exception (qui n'est pas une erreur), puis continuez, comme dans Exemple 5-13.
-
Vous devez abandonner ou fermer une ressource, comme illustré dans l'exemple suivant.
... file := UTL_FILE.OPEN ... BEGIN statement statement]... -- If this code fails for any reason, EXCEPTION WHEN OTHERS THEN UTL_FILE.FCLOSE(file); -- then you want to close the file. RAISE; -- Reraise the exception (very important). END; UTL_FILE.FCLOSE(file); ... -
Au niveau supérieur du code, lorsque vous souhaitez enregistrer l'erreur.
Par exemple, un processus client peut émettre ce bloc :
BEGIN proc(...); EXCEPTION WHEN OTHERS THEN log_error_using_autonomous_transaction(...); RAISE; -- Reraise the exception (very important). END; /Sinon, le sous-programme autonome appelé par le client peut inclure la même logique de traitement des exceptions, mais uniquement au niveau supérieur.
Traitement des exceptions prédéfinies
Vous pouvez gérer les exceptions prédéfinies. Exemple 5-13 montre comment modifier la procédure EMP_EVAL.EVAL_DEPARTMENT pour traiter l'exception prédéfinie NO_DATA_FOUND. Effectuez cette modification et compilez la procédure modifiée. (Pour un exemple de modification du corps d'un package, voir "Tutoriel : Déclaration de variables et de constantes dans un sous-programme".)
Exemple 5-13 : Traitement de l'exception prédéfinie NO_DATA_FOUND
PROCEDURE eval_department(dept_id IN employees.department_id%TYPE) AS
emp_cursor emp_refcursor_type;
current_dept departments.department_id%TYPE;
BEGIN
current_dept := dept_id;
FOR loop_c IN 1..3 LOOP
OPEN emp_cursor FOR
SELECT *
FROM employees
WHERE current_dept = eval_department.dept_id;
DBMS_OUTPUT.PUT_LINE
('Determining necessary evaluations in department #' ||
current_dept);
eval_loop_control(emp_cursor);
DBMS_OUTPUT.PUT_LINE
('Processed ' || emp_cursor%ROWCOUNT || ' records.');
CLOSE emp_cursor;
current_dept := current_dept + 10;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('The query did not return a result set');
END eval_department;
Voir aussi : Informations de référence sur le langage PL/SQL pour Oracle Database pour plus d'informations sur les exceptions prédéfinies
Déclaration et traitement des exceptions définies par l'utilisateur
Vous pouvez déclarer et traiter les exceptions définies par l'utilisateur. Exemple 5-14 montre comment modifier la fonction EMP_EVAL.CALCULATE_SCORE pour déclarer et traiter deux exceptions définies par l'utilisateur, false_weight et false_score. Effectuez cette modification et compilez la fonction modifiée. (Pour un exemple de modification du corps d'un package, voir "Tutoriel : Déclaration de variables et de constantes dans un sous-programme".)
Exemple 5-14 : Traitement des exceptions définies par l'utilisateur
FUNCTION calculate_score ( evaluation_id IN scores.evaluation_id%TYPE
, performance_id IN scores.performance_id%TYPE )
RETURN NUMBER AS
weight_wrong EXCEPTION;
score_wrong EXCEPTION;
n_score scores.score%TYPE;
n_weight performance_parts.weight%TYPE;
running_total NUMBER := 0;
max_score CONSTANT scores.score%TYPE := 9;
max_weight CONSTANT performance_parts.weight%TYPE:= 1;
BEGIN
SELECT s.score INTO n_score
FROM SCORES s
WHERE evaluation_id = s.evaluation_id
AND performance_id = s.performance_id;
SELECT p.weight INTO n_weight
FROM PERFORMANCE_PARTS p
WHERE performance_id = p.performance_id;
BEGIN
IF (n_weight > max_weight) OR (n_weight < 0) THEN
RAISE weight_wrong;
END IF;
END;
BEGIN
IF (n_score > max_score) OR (n_score < 0) THEN
RAISE score_wrong;
END IF;
END;
running_total := n_score * n_weight;
RETURN running_total;
EXCEPTION
WHEN weight_wrong THEN
DBMS_OUTPUT.PUT_LINE(
'The weight of a score must be between 0 and ' || max_weight);
RETURN -1;
WHEN score_wrong THEN
DBMS_OUTPUT.PUT_LINE(
'The score must be between 0 and ' || max_score);
RETURN -1;
END calculate_score;
Voir aussi : Informations de référence sur le langage PL/SQL pour Oracle Database pour plus d'informations sur les exceptions définies par l'utilisateur