Les étapes suivantes vous permettront de créer des procédures stockées utilisant les gestionnaires pour intercepter les exceptions.
Dans cette démonstration, nous souhaitons créer une procédure stockée qui copie une table sous un autre nom. Cependant, elle ne doit pas planter si jamais il y avait déjà une table portant le nouveau nom.
Il existe deux types de code : le code d’erreur SQL ou le code d’erreur MySQL. Vous pouvez utiliser l'un ou l'autre, à votre convenance.
Si vous reproduisez l’erreur dans PHPMyAdmin, c’est le code MySQL que vous obtiendrez.
Dans phpMyAdmin, on voit que le code de l’erreur est 1050. Il s’agit du code MySQL.
Si vous désirez obtenir les deux codes, vous devez reproduire l’erreur à la ligne de commande.
On voit ici les deux codes d’erreur : le code MySQL est 1050 et le code SQL est 42S01.
Error number: 1050; Symbol: ER_TABLE_EXISTS_ERROR; SQLSTATE: 42S01
Message: Table '%s' already exists
Déclarer la procédure stockée ainsi que les variables locales dont elle aura besoin.
Ex :
CREATE PROCEDURE copier_table_mecaniciens(OUT code_erreur INT)
BEGIN
-- (entête standard)
-- déclaration de variables locales
DECLARE nombre INT;
...
END$$
Comme nous aurons besoin de travailler avec un code d'erreur et que le code en soi n'indique pas la nature de l'erreur, nous allons utiliser une condition pour nommer l'erreur. Une condition n'est rien d'autre qu'un nom qu'on associe à un code d'erreur afin de faciliter la lecture de la procédure stockée.
Dans la procédure stockée, déclarer une condition associée à cette erreur à l’aide de la commande suivante :
DECLARE nom_condition CONDITION FOR valeur_condition;
valeur_condition peut représenter :
ou
Ex :
DECLARE table_existe_deja CONDITION FOR 1050;
ou
DECLARE table_existe_deja CONDITION FOR SQLSTATE '42S01';
Toujours dans la procédure stockée, déclarer un gestionnaire associé à la condition à l’aide de la commande suivante.
Attention : il faut déclarer les gestionnaires APRÈS toute autre variable locale et AVANT toute autre instruction.
DECLARE type_de_gestionnaire HANDLER FOR condition commande_à_exécuter;
type_de_gestionnaire peut prendre les valeurs suivantes :
condition peut prendre les valeurs suivantes :
commande_à_exécuter est une commande qui sera exécutée lorsque la condition surviendra. Il s’agit généralement d’assigner une valeur à une variable qui pourra être utilisée dans un programme PHP ou dans la procédure stockée, par exemple pour mettre fin à une boucle. Il est également possible d'effectuer plusieurs commandes, en les entourant de BEGIN et de END.
Voir le manuel en ligne de MySQL pour la syntaxe complète :
"13.6.7.2 DECLARE ... HANDLER Syntax". MySQL. http://dev.mysql.com/doc/refman/5.7/en/declare-handler.html
Ex :
DECLARE CONTINUE HANDLER FOR table_existe_deja SET continuer=0;
ou
DECLARE EXIT HANDLER FOR table_existe_deja SET code_erreur=1;
Si vous désirez réagir à toute forme d'erreur qui ne soit ni un SQLWARNING, ni un NOT FOUND, vous pouvez utiliser SQLEXCEPTION.
Ex :
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET code_erreur=-1;
Poursuivre le développement de la procédure stockée et utiliser au besoin la variable initialisée par le gestionnaire pour contrôler le traitement.
Ex :
CREATE PROCEDURE copier_table_mecaniciens(OUT code_erreur INT)
BEGIN
-- Copie la table mecaniciens dans copiemecaniciens
-- Programmé par : Annie Gagnon
-- Le : 2 novembre 2013
-- Paramètres : OUT INT code de l'erreur rencontrée
-- Valeurs possibles :
-- 0 : copie effectuée avec succès
-- -1 : copie non effectuée, erreur non déterminée
-- -2 : copie non effectuée car aucune donnée à copier
-- 1050 : copie non effectuée car la table copiemecaniciens existait déjà.
-- Historique des modifications
-- Par :
-- Le :
-- Modifications :
-- déclaration de variables locales
DECLARE nombre INT;
-- 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 = 1050;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET code_erreur = -1;
-- 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 != 0 THEN
INSERT INTO journalerreurs (message) VALUES (CONCAT('Erreur lors de la copie :', code_erreur));
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$$
▼Publicité Le texte se poursuit plus bas
« 13.6.7.2 DECLARE ... HANDLER Syntax ». MySQL. http://dev.mysql.com/doc/refman/5.7/en/declare-handler.html
« Appendix B Errors, Error Codes, and Common Problems ». MySQL. http://dev.mysql.com/doc/refman/5.7/en/error-handling.html
« MySQL Error Codes ». briandunning.com. http://www.briandunning.com/error-codes/?source=MySQL
Site fièrement hébergé chez A2 Hosting.