Exemple de boucle For dans MySQL

104

Dans MySQL, j'ai cette procédure stockée avec une boucle For:

DELIMITER $$  
CREATE PROCEDURE ABC()

   BEGIN
      DECLARE a INT Default 0 ;
      simple_loop: LOOP
         SET a=a+1;
         select a;
         IF a=5 THEN
            LEAVE simple_loop;
         END IF;
   END LOOP simple_loop;
END $$

Il imprime toujours 1. Quelle est la syntaxe correcte pour une boucle MySQL for?

Chitresh
la source
Cela crée des noms de procédure de magasin ABC. Quel est votre format de données (celui que vous souhaitez charger)?.
Zimbabwe
je ne veux aucun format de données, je veux juste imprimer une valeur de 1 à 5
Chitresh
J'ai juste essayé ce code et cela a fonctionné pour moi. J'ai dû ajouter CALL ABC (); mais cela a fonctionné. J'ai également ajouté DROP PROCEDURE ABC () à la fin car je ne l'exécutais que comme test.
Alan Stewart

Réponses:

143
drop table if exists foo;
create table foo
(
id int unsigned not null auto_increment primary key,
val smallint unsigned not null default 0
)
engine=innodb;

drop procedure if exists load_foo_test_data;

delimiter #
create procedure load_foo_test_data()
begin

declare v_max int unsigned default 1000;
declare v_counter int unsigned default 0;

  truncate table foo;
  start transaction;
  while v_counter < v_max do
    insert into foo (val) values ( floor(0 + (rand() * 65535)) );
    set v_counter=v_counter+1;
  end while;
  commit;
end #

delimiter ;

call load_foo_test_data();

select * from foo order by id;
Jon Black
la source
Merci pour votre réponse, cela m'a aidé. Pourriez-vous avoir la gentillesse de voir également ma question stackoverflow.com/questions/12259675/… . Ma question principale est la suivante: est-il nécessaire d'utiliser BEGIN...ENDet de créer une procédure si je ne veux l'utiliser que LOOP?
Vert le
1
Si vous rencontrez des problèmes avec les délimiteurs, lisez stackoverflow.com/a/10259528/632951
Pacerier
61

Exemple de syntaxe de boucle dans MySQL:

delimiter //

CREATE procedure yourdatabase.while_example()
wholeblock:BEGIN
  declare str VARCHAR(255) default '';
  declare x INT default 0;
  SET x = 1;

  WHILE x <= 5 DO
    SET str = CONCAT(str,x,',');
    SET x = x + 1;
  END WHILE;

  select str;
END//

Quelles impressions:

mysql> call while_example();
+------------+
| str        |
+------------+
| 1,2,3,4,5, |
+------------+

Exemple de syntaxe de boucle REPEAT dans MySQL:

delimiter //

CREATE procedure yourdb.repeat_loop_example()
wholeblock:BEGIN
  DECLARE x INT;
  DECLARE str VARCHAR(255);
  SET x = 5;
  SET str = '';

  REPEAT
    SET str = CONCAT(str,x,',');
    SET x = x - 1;
    UNTIL x <= 0
  END REPEAT;

  SELECT str;
END//

Quelles impressions:

mysql> call repeat_loop_example();
+------------+
| str        |
+------------+
| 5,4,3,2,1, |
+------------+

Exemple de syntaxe de boucle FOR dans MySQL:

delimiter //

CREATE procedure yourdatabase.for_loop_example()
wholeblock:BEGIN
  DECLARE x INT;
  DECLARE str VARCHAR(255);
  SET x = -5;
  SET str = '';

  loop_label: LOOP
    IF x > 0 THEN
      LEAVE loop_label;
    END IF;
    SET str = CONCAT(str,x,',');
    SET x = x + 1;
    ITERATE loop_label;
  END LOOP;

  SELECT str;

END//

Quelles impressions:

mysql> call for_loop_example();
+-------------------+
| str               |
+-------------------+
| -5,-4,-3,-2,-1,0, |
+-------------------+
1 row in set (0.00 sec)

Suivez le tutoriel: http://www.mysqltutorial.org/stored-procedures-loop.aspx

Si je vous surprends à mettre en production ce type de constructions MySQL for-loop, je vais vous tirer dessus avec le lanceur de missiles en mousse. Vous pouvez utiliser une clé à pipe pour cogner dans un clou, mais cela vous donne un air idiot.

Eric Leschinski
la source
2
Suite au code que vous avez donné, taper declare str VARCHAR(255) default '';dans la console MySQL (5.6) me donne le message d'erreur Error 1064 (42000): ... for the right syntax to use near '' at line 3, qui est aussi clair que de la boue (bien que je suppose que cela n'aime pas la clause DEFAULT).
Agi Hammerthief
Il fonctionnait dans les versions précédentes. Je pense que c'est le délimiteur de fin de ligne à changer: utilisez la commande delimiter //avant d'exécuter ceci.
Eric Leschinski
Pouvons-nous utiliser Iterate et Leave within While également? Ceux-ci agissent comme continue et pause. Iterate fonctionne-t-il de la même manière que pour continuer en Java?
Deepak
13

Supposons que vous ayez une table avec le nom «table1». Il contient une colonne «col1» de type varchar. La requête vers la table de caisse est donnée ci-dessous

CREATE TABLE `table1` (
    `col1` VARCHAR(50) NULL DEFAULT NULL
)

Maintenant, si vous souhaitez insérer un nombre de 1 à 50 dans cette table, utilisez la procédure stockée suivante

DELIMITER $$  
CREATE PROCEDURE ABC()

   BEGIN
      DECLARE a INT Default 1 ;
      simple_loop: LOOP         
         insert into table1 values(a);
         SET a=a+1;
         IF a=51 THEN
            LEAVE simple_loop;
         END IF;
   END LOOP simple_loop;
END $$

Pour appeler cette procédure stockée, utilisez

CALL `ABC`()
Fathah Rehman P
la source
1

Vous pouvez échanger cette variable locale contre une variable globale, ce serait plus simple.

DROP PROCEDURE IF EXISTS ABC;
DELIMITER $$  
CREATE PROCEDURE ABC()

   BEGIN
      SET @a = 0;
      simple_loop: LOOP
         SET @a=@a+1;
         select @a;
         IF @a=5 THEN
            LEAVE simple_loop;
         END IF;
   END LOOP simple_loop;
END $$
Bruno Henrique
la source