On utilisera souvent une boucle pour traiter chaque ligne extraite par la requête. On aura besoin pour cela des gestionnaires. En effet, quand la boucle aura traité le dernier enregistrement retourné par la requête et qu'elle tentera d'aller à l'enregistrement suivant, une exception sera levée. Vous devrez récupérer cette exception et faire en sorte que la boucle se termine.
Puisque c'est l'instruction FETCH qui permet de passer à l'enregistrement suivant, il faudra vérifier tout de suite après le FETCH si la fin n'est pas atteinte. Le traitement de l'enregistrement sera donc fait à l'intérieur d'une condition s'assurant que l'exception n'a pas encore été levée. Si vous omettez cette vérification, le dernier enregistrement sera traité deux fois.
Le code de la procédure stockée aura donc la forme suivante :
CREATE PROCEDURE traiter_mecaniciens()
BEGIN
-- entête standard
-- déclaration de variables locales
DECLARE l_id INT;
DECLARE l_prenom VARCHAR(45);
DECLARE l_nomfamille VARCHAR(45);
DECLARE mysql_errno INT;
DECLARE message_text TEXT;
DECLARE fini BOOL DEFAULT 0;
-- déclaration de curseurs
DECLARE c_mecaniciens CURSOR FOR SELECT id, prenom, nomfamille FROM mecaniciens;
-- déclaration de gestionnaires
DECLARE CONTINUE HANDLER FOR NOT FOUND SET fini=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));
END;
-- traitement
OPEN c_mecaniciens;
WHILE NOT fini DO
FETCH c_mecaniciens INTO l_id, l_prenom, l_nomfamille;
IF NOT fini THEN
-- Entrez ici les instructions à exécuter pour chaque enregistrement retrouvé par le SELECT du curseur
...
-- Enlever le commentaire devant la ligne suivante pour faciliter le débogage de la boucle
-- INSERT INTO journalerreurs(message) VALUES(CONCAT('id du mécanicien: ', l_id));
END IF;
END WHILE;
CLOSE c_mecaniciens;
END$$
Notez la présence d'un gestionnaire sur SQLEXCEPTION. Ce gestionnaire n'est pas nécessaire pour effectuer la boucle mais il vous sera utile pour déboguer votre procédure stockée.
Notez également la présence, à l'intérieur de la boucle, d'une instruction qui fait une écriture au journal des erreurs. Elle a été mise en commentaire mais lors du débogage, vous pourrez enlever la marque de commentaire et l'adapter afin de mieux cerner les problèmes dans votre procédure.
▼Publicité