Formation PUB200 : MySQL, 2018 Les curseurs

18.3 Boucler dans les résultats de la requête


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 :

MySQL

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é

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre