Bonjour,
Un peu toute récente aussi dans le domaine des procédures mysql, je te propose la solution suivante via un Curseur, je ne doute pas qu'il doit exister une autre solution, plus rapide, plus in, plus... que les vrais pros du sql et de tout le tuttifrutti pourrait faire super rapidement (mais bon faut bien débuter dans la vie!!!)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| CREATE PROCEDURE `modif`(IN pmenu VARCHAR(10),IN nv_position INT)
BEGIN
DECLARE hasMoreRows BOOLEAN default FALSE;
DECLARE CONTINUE HANDLER FOR 1329 set hasMoreRows := TRUE; -- Gestion d'erreur pour fin curseur atteinte
BEGIN
DECLARE cur_menu VARCHAR(10); -- Variable permettant de stocker le contenu du champ "menu" en cours du curseur
DECLARE cur_position INT; -- Variable permettant de stocker le contenu du champ "position" en cours du curseur
DECLARE cur1 CURSOR FOR SELECT menu, position FROM test; -- Création du curseur
SELECT position INTO @old_position FROM test WHERE menu = pmenu; --Stockage de l'ancienne position du menu à modifier
OPEN cur1; -- Ouverture du curseur
CURSOR_LOOP: loop --Début de la boucle de lecture du curseur
FETCH cur1 INTO cur_menu, cur_position; --Instanciation des variables sur enregistrement en cours du curseur
IF (( hasMoreRows ) OR (cur_position > @old_position))then -- S'il n'y a plus d'enregistrement dans le curseur et si la position du curseur est supérieur à l'ancienne position
CLOSE cur1; -- Fermeture du curseur
leave cursor_loop; -- Sortie de la boucle
END IF;
IF (cur_position = nv_position) THEN -- Si la position du curseur est égal à la nouvelle (position recherché)
UPDATE test SET menu = pmenu where position = cur_position; -- On remplace l'ancienne valeur du champ "menu" de la table test par le nouveau menu
ELSE
IF ((cur_position >= nv_position) AND ((cur_position+1) <= @old_position)) THEN
UPDATE test SET menu = cur_menu where position = cur_position + 1; -- Décalage d'une position le champs "menu" par celui contenu dans le curseur mais à position+1
END IF;
END IF;
END LOOP cursor_loop; -- Sortie de la boucle
END;
END |
Bon, je pense qu'une explication s'impose....
1) On crée un curseur sur la table test (Un curseur SQL représente une zone de mémoire de la base de données où la dernière instruction SQL est stockée.)
2) Dans une variable de session nommé @old_position on stocke la valeur de l'ancienne position du menu à modifier.
3) Pour chaque enregistrement du curseur, on teste :
1 - si l'ancienne position du menu est supérieur à la position actuelle du curseur ou si l'erreur 1329 est levé (j'expliquerai plus bas le coup de 1329), on ferme le curseur et on sort de la boucle..., sinon on poursuit le programme[/I]
2 - si la position du curseur est la même que la nouvelle position passé en paramètre, alors on change l'intitulé du menu (dans votre exemple, menu1 est remplacé par menu 2)
3 - si la position du curseur est supérieur ou égal à la nouvelle position et si elle est inférieur à l'ancienne, alors on copie le contenu du champ menu du curseur dans la table test à la position du curseur + 1
Si l'exception n°1329 n'est pas géré, une erreur sera levé à cause du test cur_position+1 (on test un enregistrement inexistant), donc pour y palier on ajoute la gestion d'erreur avec les lignes :
DECLARE hasMoreRows BOOLEAN DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR 1329 SET hasMoreRows := TRUE;
Je ne suis pas sur que mon explication soit super clair donc si vous avez des questions n'hésitez pas, par contre le mieux pour comprendre est de tester ce programme dans tout les sens (retiré des if... en rajouter...)
Bon courage!!!
Partager