Dans vos procédures et fonctions stockées, vous devriez toujours prévoir tous les cas d'erreur possibles. Comme il serait fastidieux de créer un gestionnaire pour chacune des exceptions imaginable, on utilisera plutôt un gestionnaire pour l'exception SQLEXCEPTION.
Lorsqu'une erreur inattendue est détectée par SQLEXCEPTION, on voudra savoir qu'est-ce qui a causé le problème exactement.
Avec un gestionnaire sur SQLEXCEPTION qui vous donne de l'information sur l'erreur rencontrée, le débogage de vos procédures et fonctions stockées sera plus facile.
L'instruction GET DIAGNOSTICS, placée à l'intérieur d'un DECLARE CONTINUE HANDLER, permet de retrouver de l'information sur l'exception qui a été levée, par exemple le code de l'erreur et son message. Ces informations seront stockées dans des variables et pourront être utilisées plus tard.
GET DIAGNOSTICS utilise la syntaxe suivante :
GET DIAGNOSTICS CONDITION numero_condition
variable_1 = information_1,
variable_2 = information_2;
Comme numéro de condition, nous utiliserons presque toujours la valeur 1. Un autre numéro pourrait être utilisé dans le cas où l'instruction GET DIAGNOSTICS ou RESIGNAL aurait elle-même levé une exception, tel que démontré ici : http://dev.mysql.com/doc/refman/5.7/en/diagnostics-area.html#diagnostics-area-populating. Comme il s'agit d'un cas très particulier, nous nous en tiendrons au numéro 1.
La liste des informations pouvant être retrouvées par GET DIAGNOSTICS comprend :
Pour une description de ces informations, consultez cette page : http://dev.mysql.com/doc/refman/5.7/en/diagnostics-area.html#diagnostics-area-information-items.
Ex :
GET DIAGNOSTICS CONDITION 1
mysql_errno = MYSQL_ERRNO,
message_text = MESSAGE_TEXT;
Voici comment imbriquer un GET DIAGNOSTICS à l'intérieur du gestionnaire pour l'exception SQLEXCEPTION :
CREATE PROCEDURE copier_table_mecaniciens(OUT code_erreur INT)
BEGIN
-- Copie la table mecaniciens dans copiemecaniciens
-- Programmé par : Annie Gagnon
-- Le : 2 novembre 2016
-- Paramètres : OUT code de l'erreur rencontrée
-- Valeurs possibles :
-- 0 : copie effectuée avec succès
-- -1 : copie non effectuée car la table copiemecaniciens existait déjà
-- -2 : copie non effectuée car aucune donnée à copier
-- Autre nombre : une erreur est survenue. La valeur de retour constitue le code MySQL de l'erreur.
-- Historique des modifications
-- Par : Annie Gagnon
-- Le : 8 novembre 2016
-- Modifications : En cas d'erreur autre que table_existe_deja,
-- enregistre le code et le message d'erreur dans le journal des erreurs.
-- La valeur de retour sera -1 (et non plus 1050) quand la table existait déjà.
-- Pour toute autre erreur, c'est le code d'erreur MySQL qui sera la valeur de retour.
-- déclaration de variables locales
DECLARE nombre INT;
DECLARE mysql_errno INT;
DECLARE message_text TEXT;
-- déclaration de conditions
DECLARE table_existe_deja CONDITION FOR 1050;
-- déclaration de gestionnaires
DECLARE CONTINUE HANDLER FOR table_existe_deja SET code_erreur=-1;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
-- retrouve les informations sur l'erreur
GET DIAGNOSTICS CONDITION 1
mysql_errno = MYSQL_ERRNO,
message_text = MESSAGE_TEXT;
-- enregistre les informations sur l'erreur dans le journal des erreurs
INSERT INTO journalerreurs (message) VALUES (CONCAT('Erreur inattendue :', mysql_errno, ': ', message_text));
-- initialise la valeur de retour
SET code_erreur = mysql_errno;
END;
-- traitement
SET code_erreur=0;
SELECT COUNT(*) INTO nombre FROM mecaniciens;
IF nombre > 0 THEN
CREATE TABLE copiemecaniciens AS (SELECT * FROM mecaniciens);
IF code_erreur = -1 THEN
-- pour tous les autres codes d'erreur, le gestionnaire de SQLEXCEPTION a déjà fait l'insertion
INSERT INTO journalerreurs (message) VALUES ('La table copiemecaniciens existait déjà. La copie n''a pas eu lieu.');
END IF;
ELSE
-- le programme PHP saura que la valeur -2 signifie que la table n'a pas été créée pcq rien à copier dedans
SET code_erreur=-2;
END IF;
END$$
« GET DIAGNOSTICS Syntax ». MySQL. http://dev.mysql.com/doc/refman/5.7/en/get-diagnostics.html
« GET DIAGNOSTICS ». SQL And Its Sequels. http://ocelot.ca/blog/blog/2014/11/16/get-diagnostics/
« Using GET DIAGNOSTICS in MySQL 5.6 ». Guy Harrison's web bits. http://guyharrison.squarespace.com/blog/2013/7/5/using-get-diagnostics-in-mysql-56.html
▼Publicité