web-dev-qa-db-fra.com

Comment faire des boucles While?

Comment utiliser les boucles while dans MySQL? Mon script de test:

BEGIN
    SELECT 0 INTO @n;
    WHILE @n < 10 DO
    SELECT @n;
    SET @n := @n +1;
    END WHILE;
END;

Mais il a des erreurs de syntaxe. J'exécute la boucle en utilisant le client SQLyog dans une fenêtre de requête standard. Les erreurs de syntaxe se présentent sous la forme suivante:

Code d'erreur: 1064
Vous avez une erreur dans votre syntaxe SQL; consultez le manuel qui correspond à votre version de serveur MySQL pour la bonne syntaxe à utiliser près de ...

J'ai également essayé d'utiliser l'exemple de boucle while fourni par https://dev.mysql.com/doc/refman/5.6/en/ While.html mais cela n'a toujours pas fonctionné.

Quelle partie du script est incorrecte? (Utilisation de MySQL 5.6.)

J'essaie de faire une moyenne mobile sur 6 mois de certaines données, donc j'espérais qu'une boucle while pourrait ajouter la "nouvelle" moyenne sur 6 mois à la "vieille" moyenne sur 6 mois à chaque itération de la boucle.

7

Vous ne pouvez pas faire de boucle for dans un éditeur SQL sans procédure stockée. J'utilise MySQL Workbench pour faire cela.

Une procédure stockée rapide devrait faire le travail:

DROP PROCEDURE IF EXISTS proc_loop_test;
CREATE PROCEDURE proc_loop_test()
BEGIN
  DECLARE int_val INT DEFAULT 0;
  test_loop : LOOP
    IF (int_val = 10) THEN
      LEAVE test_loop;
    END IF;

    SET int_val = int_val +1;
    SELECT int_val; 
  END LOOP; 
END;
10
oNare

Juste pour clarifier que les boucles "while" do fonctionnent:

Il a été dit à juste titre que vous devez créer une procédure stockée (ne peut pas exécuter des blocs anonymes comme dans Oracle par exemple), et cela ne fonctionne parfois pas bien dans les éditeurs SQL "génériques" (car PL/SQL ne fonctionne pas toujours eh bien non plus)

Vous pouvez utiliser MySQL Workbench, ou également la ligne de commande:

16:54 [test]:> delimiter $$
16:54 [test]:> create procedure testwhile ()
    -> begin
    ->   declare n int;
    ->   set n:=0;
    ->   while n <10 do
    ->     select n;
    ->     set n := n+1;
    ->   end while;
    -> end;
    -> $$
Query OK, 0 rows affected (0.00 sec)
16:54 [test]:> delimiter ;
16:54 [test]:> call testwhile();
[...]

En remarque, @variables fonctionne également mais ce sont des variables de session. Dans ce cas, je préfère les variables de procédure stockée locales (ne peut pas être vu ou modifié en dehors de la portée de la procédure)

5
phil_w

J'ai rencontré un problème avec des plaintes d'erreur de syntaxe déroutantes de mysql workbench, malgré des exemples de collage de copie trouvés dans la documentation officielle et d'autres réponses du site d'échange de pile. Si vous avez une longue requête divisée en plusieurs lignes (pour la lisibilité humaine), vous devrez peut-être utiliser un délimiteur pour indiquer plus clairement à la machine quels sauts de ligne sont "significatifs".

Un exemple d'une requête multi-lignes (bien que modifiée) dans une procédure qui a été acceptée par moi par MySQL Workbench.

DELIMITER //
DROP PROCEDURE IF EXISTS methodLoop;
CREATE PROCEDURE methodLoop(p1 INT)
BEGIN
    label1: LOOP
        SET p1 = p1-1;
        IF p1 > 0 THEN

            SELECT *
            FROM Table1 foo
            LEFT JOIN Table 2 bar ON foo.id = bar.id;

        END IF;

    END LOOP label1;
END//

DELIMITER ;

call methodLoop(10);

https://stackoverflow.com/questions/52412225/mysql-create-insert-procedure-statement-incomplete

0
user1821961