Les exceptions Une exception est un identificateur PL/SQL détecté pendant la phase d’exécution. Comment est-elle déclenchée ? À la suite d’une erreur Oracle Explicitement, par le programme Comment la traiter ? En l’interceptant à l’aide d’un gestionnaire En la propageant à l’environnement appelant
Traiter les exceptions Intercepter l'exception Propager l'exception DECLARE BEGIN END; Exception déclenchée EXCEPTION Exception interceptée DECLARE BEGIN END; Exception déclenchée EXCEPTION Exception non interceptée Exception propagée à l'environnement appelant Intercepter une exception Si une exception se déclenche dans la section exécutable du bloc, le programme effectue un branchement sur le gestionnaire d'exceptions correspondant dans la section de traitement des exceptions du bloc. Si PL/SQL traite convenablement l'exception, celle-ci n'est pas propagée au bloc englobant ou à l'environnement appelant. Le bloc PL/SQL s'exécute correctement. Propager une exception Si une exception se produit dans la section exécutable du bloc et qu'il n'y a pas de gestionnaire d'exceptions correspondant, le bloc PL/SQL aboutit à une erreur et l'exception est propagée à l'environnement appelant.
Types d’exception EXCEPTION DESCRIPTION UTILISATION Exception prédéfinie du serveur Oracle L’une des vingt erreurs les plus fréquentes en PL/SQL Ne pas déclarer ces exceptions et autoriser le serveur Oracle à les déclencher implicitement Exception non prédéfinie du serveur Oracle Toute erreur standard du serveur Oracle Déclarer ces exceptions dans la section déclarative et autoriser le serveur Oracle à les déclencher implicitement Exception définie par l’utilisateur Condition anormale déterminée par le développeur Déclarer ces exceptions dans la section déclarative et déclencher-les explicitement
Exception : interception WHEN exception1 [or exception2. . .] THEN statement1; statement2; . . . [WHEN exception3 [OR exception4. . .] THEN . . . ] [WHEN OTHERS THEN . . .]
Exceptions : règles d’interception Le mot clé EXCEPTION débute la section de traitement des exceptions Plusieurs gestionnaires d’exceptions sont permis Un seul gestionnaire d’exceptions est exécuté avant de sortir du bloc WHEN OTHERS est la dernière clause
Exceptions prédéfinies d’Oracle Utiliser le nom standard à l’intérieur du sous- programme de traitement des exceptions Exemples d’exceptions prédéfinies : NO_DATA_FOUND (ORA - 01403) TOO_MANY_ROWS (ORA – 01422) INVALID_CURSOR (ORA – 01001) ZERO_DIVIDE (ORA – 01476) DUP_VAL_ON_INDEX (ORA – 00001)
Exceptions prédéfinies BEGIN . . . EXCEPTION WHEN NO_DATA_FOUND THEN statement1; statement2; WHEN TOO_MANY_ROWS THEN WHEN OTHERS THEN statement3; END;
Intercepter les erreurs non prédéfinies du serveur Oracle Section déclarative Section de traitement des exceptions Déclarer Nommer l'exception Associer Coder PRAGMA EXCEPTION_INIT Référencer Traiter l'exception déclenchée Intercepter les erreurs non prédéfinies du serveur Oracle Pour intercepter une erreur non prédéfinie du serveur Oracle, vous devez déclarer celle-ci au préalable ou utiliser le gestionnaire OTHERS. Une fois l'exception déclarée, elle se déclenche implicitement. En PL/SQL, la clause PRAGMA EXCEPTION_INIT indique au compilateur d'associer un nom d'exception à un code d'erreur Oracle. Ainsi, vous pouvez faire référence à une exception interne par son nom et lui associer un gestionnaire spécifique. Remarque : PRAGMA (appelé aussi pseudo-instructions) est un mot-clé qui signifie que l'instruction est destinée au compilateur et qu'elle n'est donc pas traitée au moment de l'exécution du bloc PL/SQL. Par ailleurs, ce mot-clé oblige le compilateur PL/SQL à interpréter chaque occurrence de l'exception dans le bloc par un code d'erreur du serveur Oracle.
Erreur non prédéfinie Intercepter une violation de contrainte d'intégrité (code d'erreur du serveur Oracle –2292). DEFINE p_deptno = 10 DECLARE e_emps_remaining EXCEPTION; PRAGMA EXCEPTION_INIT (e_emps_remaining, -2292); BEGIN DELETE FROM departments WHERE department_id = &p_deptno; COMMIT; EXCEPTION WHEN e_emps_remaining THEN DBMS_OUTPUT.PUT_LINE ('Cannot remove dept ' || TO_CHAR(&p_deptno) || '. Employees exist. '); END; 1 2 Intercepter une exception non prédéfinie du serveur Oracle 1. Déclarez le nom de l'exception dans la section déclarative. Syntaxe exception EXCEPTION; où : exception correspond au nom de l'exception. 2. Utilisez l'instruction PRAGMA EXCEPTION_INIT pour associer l'exception déclarée au code d'erreur standard du serveur Oracle. PRAGMA EXCEPTION_INIT(exception, error_number); où : exception correspond à l'exception déclarée préalablement. error_number correspond à un code d'erreur standard du serveur Oracle. 3. Faites référence à l'exception ainsi déclarée dans le sous-programme correspondant de traitement des exceptions. Exemple Si un service compte des employés, affichez un message à l'utilisateur l'informant que ce service ne peut pas être supprimé. 3
Fonctions d'interception des exceptions SQLCODE : renvoie la valeur numérique du code d'erreur SQLERRM : renvoie le message associé au code d'erreur Fonctions d'interception des erreurs Lorsqu'une exception se produit, vous pouvez identifier le code ou le message d'erreur associé en utilisant deux fonctions. D'après le message ou le code d'erreur, vous pouvez décider de l'action à entreprendre. SQLCODE renvoie le code d'erreur du serveur Oracle pour les exceptions internes. Vous pouvez transmettre le code d'erreur à SQLERRM, qui renvoie alors le message associé. Exemples de valeurs SQLCODE
Fonctions d'interception des exceptions Exemple : DECLARE v_error_code NUMBER; v_error_message VARCHAR2(255); BEGIN ... EXCEPTION WHEN OTHERS THEN ROLLBACK; v_error_code := SQLCODE ; v_error_message := SQLERRM ; INSERT INTO errors VALUES(v_error_code, v_error_message); END; Fonctions d'interception des erreurs (suite) Vous pouvez utiliser un ensemble de fonctions génériques pour identifier les exceptions interceptées dans le gestionnaire WHEN OTHERS. L'exemple de la diapositive illustre l'affectation des valeurs de SQLCODE et de SQLERRM à des variables, puis l'utilisation de ces variables dans une instruction SQL. Vous ne pouvez pas utiliser SQLCODE ni SQLERRM directement dans une instruction SQL. Vous devez affecter leur valeur à des variables locales, puis utiliser ces variables dans l'instruction SQL, comme le montre l'exemple présenté sur la diapositive : DECLARE err_num NUMBER; err_msg VARCHAR2(100); BEGIN ... EXCEPTION ... WHEN OTHERS THEN err_num := SQLCODE; err_msg := SUBSTR(SQLERRM, 1, 100); INSERT INTO errors VALUES (err_num, err_msg); END;
Intercepter les exceptions définies par l'utilisateur Section déclarative Section exécutable Section de traitement des exceptions Déclencher Déclencher explicitement l'exception par l'instruction RAISE. Référencer Traiter l'exception déclenchée. Nommer l'exception. Déclarer Intercepter les exceptions définies par l'utilisateur Le langage PL/SQL vous permet de définir vos propres exceptions. Les exceptions définies par l'utilisateur en PL/SQL doivent être : déclarées dans la section déclarative d'un bloc PL/SQL, déclenchées explicitement avec l'instruction RAISE.
Exceptions définies par l'utilisateur Exemple : DEFINE p_department_desc = 'Information Technology ' DEFINE P_department_number = 300 DECLARE e_invalid_department EXCEPTION; BEGIN UPDATE departments SET department_name = '&p_department_desc' WHERE department_id = &p_department_number; IF SQL%NOTFOUND THEN RAISE e_invalid_department; END IF; COMMIT; EXCEPTION WHEN e_invalid_department THEN DBMS_OUTPUT.PUT_LINE('No such department id.'); END; 1 2 Intercepter les exceptions définies par l'utilisateur (suite) Pour intercepter une exception définie par l'utilisateur, vous devez la déclarer et la déclencher explicitement. 1. Déclarez le nom de l'exception définie par l'utilisateur dans la section déclarative. Syntaxe : exception EXCEPTION; où : exception correspond au nom de l'exception 2. Utilisez l'instruction RAISE pour déclencher explicitement l'exception dans la section exécutable. RAISE exception; où : exception correspond à l'exception préalablement déclarée 3. Faites référence à l'exception ainsi déclarée dans le sous-programme correspondant de traitement des exceptions. Exemple Le bloc permet de mettre à jour la description d'un service. L'utilisateur entre le code du service et son nouveau nom. Si l'utilisateur entre un code de service qui n'existe pas, aucune ligne n'est mise à jour dans la table DEPARTMENTS. Une exception est déclenchée et un message avertit l'utilisateur qu'il a saisi un code de service incorrect. Remarque : Utilisez l'instruction RAISE dans un gestionnaire d'exceptions pour renvoyer la même exception à l'environnement appelant. 3
Procédure RAISE_APPLICATION_ERROR Syntaxe : La procédure permet de délivrer des messages d'erreur définis par l'utilisateur à partir de sous- programmes stockés. Elle permet de signaler les erreurs à l'application et d'éviter le renvoi d'exceptions non traitées. raise_application_error (error_number, message[, {TRUE | FALSE}]); Procédure RAISE_APPLICATION_ERROR Grâce à la procédure RAISE_APPLICATION_ERROR, délivrez de manière interactive une exception prédéfinie en renvoyant un code et un message d'erreur non-standard. RAISE_APPLICATION_ERROR permet de signaler les erreurs à l'application et d'éviter le renvoi d'exceptions non traitées. Dans la syntaxe : error_number est une valeur numérique définie par l'utilisateur pour l'exception ; cette valeur est comprise entre –20000 et –20999. message est un message défini par l'utilisateur pour l'exception ; il s'agit d'une chaîne de caractères d'une taille maximale de 2 048 octets. TRUE | FALSE est un paramètre booléen facultatif (si le paramètre est TRUE, l'erreur est rangée dans la pile des erreurs précédentes. Si le paramètre est FALSE, valeur par défaut, l'erreur remplace toutes les erreurs précédentes.)
Procédure RAISE_APPLICATION_ERROR Elle peut être utilisée à deux endroits : section exécutable section de traitement des exceptions Elle renvoie à l'utilisateur les conditions de l'erreur de manière cohérente par rapport aux autres erreurs du serveur Oracle Procédure RAISE_APPLICATION_ERROR (suite) La procédure RAISE_APPLICATION_ERROR peut être utilisée dans la section exécutable et/ou dans la section de traitement des exceptions d'un programme PL/SQL. L'erreur renvoyée est cohérente par rapport aux erreurs du serveur Oracle, qu'elles soient prédéfinies, non prédéfinies ou définies par l'utilisateur. Le code et le message d'erreur s'affichent pour l'utilisateur.
RAISE_APPLICATION_ERROR Section exécutable : BEGIN ... DELETE FROM employees WHERE manager_id = v_mgr; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR(-20202, 'This is not a valid manager'); END IF; Section de traitement des exceptions : Exemple Dans l'exemple présenté sur la diapositive, la procédure RAISE_APPLICATION_ERROR peut être utilisée à la fois dans la section exécutable et dans la section de traitement des exceptions d'un programme PL/SQL. Voici un autre exemple d'utilisation de la procédure RAISE_APPLICATION_ERROR dans la section exécutable et dans la section de traitement des exceptions d'un programme PL/SQL : DECLARE e_name EXCEPTION; PRAGMA EXCEPTION_INIT (e_name, -20999); BEGIN ... DELETE FROM employees WHERE last_name = 'Higgins'; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR(-20999,'This is not a valid last name'); END IF; EXCEPTION WHEN e_name THEN -- handle the error ... END; / ... EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR (-20201, 'Manager is not a valid employee.'); END;