Travailler avec des boucles¶
Exécution de scripts Snowflake prend en charge les types de boucles suivants :
Cette rubrique explique comment utiliser chacun de ces types de boucles.
Dans ce chapitre :
Boucle FOR¶
Une boucle FOR répète une séquence d’étapes pour un nombre spécifié de fois ou pour chaque ligne d’un jeu de résultats. Exécution de scripts Snowflake prend en charge les types suivants de boucles FOR
:
Les sections suivantes expliquent comment utiliser ces types de boucles FOR.
Boucles FOR basées sur le compteur¶
Une boucle FOR
basée sur un compteur s’exécute un nombre déterminé de fois.
La syntaxe d’une boucle FOR basée sur un compteur est la suivante
FOR <counter_variable> IN [ REVERSE ] <start> TO <end> { DO | LOOP } <statement>; [ <statement>; ... ] END { FOR | LOOP } [ <label> ] ;
Par exemple, la boucle suivante FOR s’exécute 5 fois :
DECLARE counter INTEGER DEFAULT 0; maximum_count INTEGER default 5; BEGIN FOR i IN 1 TO maximum_count DO counter := counter + 1; END FOR; RETURN counter; END;Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :
EXECUTE IMMEDIATE $$ DECLARE counter INTEGER DEFAULT 0; maximum_count INTEGER default 5; BEGIN FOR i IN 1 TO maximum_count DO counter := counter + 1; END FOR; RETURN counter; END; $$ ;
Pour une syntaxe complète et des détails sur les instructions FOR, voir FOR (Exécution de scripts Snowflake).
Boucles FOR basées sur le curseur¶
Une boucle basée sur un curseur FOR
itère sur un jeu de résultats. Le nombre d’itérations est déterminé par le nombre de lignes dans le curseur.
La syntaxe d’une boucle FOR basée sur le curseur est la suivante :
FOR <row_variable> IN <cursor_name> DO <statement>; [ <statement>; ... ] END FOR [ <label> ] ;
L’exemple suivant utilise une boucle FOR pour itérer sur les lignes d’un curseur pour la table invoices
:
CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2)); INSERT INTO invoices (price) VALUES (11.11), (22.22); DECLARE total_price FLOAT; c1 CURSOR FOR select price from invoices; BEGIN total_price := 0.0; FOR record IN c1 DO total_price := total_price + record.price; END FOR; RETURN total_price; END;Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :
CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2)); INSERT INTO invoices (price) VALUES (11.11), (22.22); EXECUTE IMMEDIATE $$ DECLARE total_price FLOAT; c1 CURSOR FOR select price from invoices; BEGIN total_price := 0.0; FOR record IN c1 DO total_price := total_price + record.price; END FOR; RETURN total_price; END; $$ ;
Pour une syntaxe complète et des détails sur les instructions FOR, voir FOR (Exécution de scripts Snowflake).
Boucle WHILE¶
Une boucle WHILE itère pendant qu’une condition est vraie. Dans une boucle WHILE
, la condition est testée immédiatement avant l’exécution du corps de la boucle. Si la condition est fausse avant la première itération, le corps de la boucle ne s’exécute pas une seule fois.
La syntaxe d’une boucle WHILE
est la suivante :
WHILE ( <condition> ) { DO | LOOP } <statement>; [ <statement>; ... ] END { WHILE | LOOP } [ <label> ] ;
Par exemple :
BEGIN LET counter := 0; WHILE (counter < 5) DO counter := counter + 1; END WHILE; RETURN counter; END;Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :
EXECUTE IMMEDIATE $$ BEGIN LET counter := 0; WHILE (counter < 5) DO counter := counter + 1; END WHILE; RETURN counter; END; $$ ;
Pour une syntaxe complète et des détails sur les instructions WHILE
, voir WHILE (Exécution de scripts Snowflake).
Boucle REPEAT¶
Une boucle REPEAT itère jusqu’à ce qu’une condition soit vraie. Dans une boucle REPEAT
, la condition est testée immédiatement après l’exécution du corps de la boucle. Par conséquent, le corps de la boucle s’exécute toujours au moins une fois.
La syntaxe d’une boucle REPEAT
est la suivante :
REPEAT <statement>; [ <statement>; ... ] UNTIL ( <condition> ) END REPEAT [ <label> ] ;
Par exemple :
BEGIN LET counter := 5; LET number_of_iterations := 0; REPEAT counter := counter - 1; number_of_iterations := number_of_iterations + 1; UNTIL (counter = 0) END REPEAT; RETURN number_of_iterations; END;Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :
EXECUTE IMMEDIATE $$ BEGIN LET counter := 5; LET number_of_iterations := 0; REPEAT counter := counter - 1; number_of_iterations := number_of_iterations + 1; UNTIL (counter = 0) END REPEAT; RETURN number_of_iterations; END; $$ ;
Pour une syntaxe complète et des détails sur les instructions REPEAT
, voir REPEAT (Exécution de scripts Snowflake).
Boucle LOOP¶
Une boucle LOOP s’exécute jusqu’à ce qu’une commande BREAK soit exécutée. Une telle commande BREAK
est normalement intégrée dans une logique « branching » (par exemple, Instructions IF ou Instructions CASE).
La syntaxe d’une instruction LOOP est la suivante :
LOOP <statement>; [ <statement>; ... ] END LOOP [ <label> ] ;
Par exemple :
BEGIN LET counter := 5; LOOP IF (counter = 0) THEN BREAK; END IF; counter := counter - 1; END LOOP; RETURN counter; END;Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :
EXECUTE IMMEDIATE $$ BEGIN LET counter := 5; LOOP IF (counter = 0) THEN BREAK; END IF; counter := counter - 1; END LOOP; RETURN counter; END; $$ ;
Pour une syntaxe complète et des détails sur les instructions LOOP
, voir LOOP (Exécution de scripts Snowflake).
Mettre fin à une boucle ou une itération¶
Dans une construction de boucle, vous pouvez spécifier quand la boucle ou une itération de la boucle doit se terminer prématurément. Les sections suivantes expliquent cela plus en détail :
Terminer une boucle¶
Vous pouvez explicitement mettre fin à une boucle de manière anticipée en exécutant la commande BREAK. BREAK
(et son synonyme EXIT
) arrête immédiatement l’itération en cours, et saute toutes les itérations restantes. Vous pouvez considérer BREAK
comme un saut à la première instruction exécutable après la fin de la boucle.
BREAK
est nécessaire dans une LOOP
mais ne l’est pas dans WHILE
, FOR
et dans REPEAT
. Dans la plupart des cas, si vous souhaitez sauter des instructions, vous pouvez utiliser les constructions « branching » standard (Instructions IF et Instructions CASE) pour contrôler les instructions exécutées dans une boucle.
Une commande BREAK
elle-même se trouve généralement à l’intérieur d’une instruction IF
(ou CASE
).
Terminer une itération sans terminer la boucle¶
Vous pouvez utiliser la commande CONTINUE
(ou ITERATE
) pour sauter à la fin d’une itération d’une boucle, en ignorant les instructions restantes de la boucle. La boucle se poursuit au début de l’itération suivante.
De tels sauts sont rarement nécessaires. Dans la plupart des cas, si vous souhaitez sauter des instructions, vous pouvez utiliser les constructions « branching » standard (Instructions IF et Instructions CASE) pour contrôler les instructions exécutées dans une boucle.
Une commande CONTINUE
ou ITERATE
se trouve généralement à l’intérieur d’une instruction IF
(ou CASE
).
Spécifier l’endroit où l’exécution doit se poursuivre après la fin de l’opération¶
Dans une commande BREAK
ou CONTINUE
, si vous devez poursuivre l’exécution à un point spécifique du code (par exemple, la boucle extérieure d’une boucle imbriquée), spécifiez une étiquette qui identifie le point auquel l’exécution doit se poursuivre.
L’exemple suivant en fait la démonstration dans une boucle imbriquée :
BEGIN LET inner_counter := 0; LET outer_counter := 0; LOOP LOOP IF (inner_counter < 5) THEN inner_counter := inner_counter + 1; CONTINUE OUTER; ELSE BREAK OUTER; END IF; END LOOP INNER; outer_counter := outer_counter + 1; BREAK; END LOOP OUTER; RETURN array_construct(outer_counter, inner_counter); END;Remarque : si vous utilisez SnowSQL ou l”Classic Console, utilisez cet exemple à la place (voir Utilisation d’Exécution de scripts Snowflake dans SnowSQL et l”Classic Console) :
EXECUTE IMMEDIATE $$ BEGIN LET inner_counter := 0; LET outer_counter := 0; LOOP LOOP IF (inner_counter < 5) THEN inner_counter := inner_counter + 1; CONTINUE OUTER; ELSE BREAK OUTER; END IF; END LOOP INNER; outer_counter := outer_counter + 1; BREAK; END LOOP OUTER; RETURN array_construct(outer_counter, inner_counter); END; $$;
Dans cet exemple :
Il existe une boucle étiquetée
INNER
qui est imbriquée dans une boucle étiquetéeOUTER
.CONTINUE OUTER
lance une autre itération de la boucle avec l’étiquetteOUTER
.BREAK OUTER
termine la boucle intérieure et transfère le contrôle à la fin de la boucle extérieure (étiquetéeOUTER
).
La sortie de cette commande est la suivante :
+-----------------+ | anonymous block | |-----------------| | [ | | 0, | | 5 | | ] | +-----------------+
Comme indiqué dans la sortie :
inner_counter
est incrémenté jusqu’à 5.CONTINUE OUTER
lance une nouvelle itération de la boucle externe, qui lance une nouvelle itération de la boucle interne, qui incrémente ce compteur jusqu’à 5.outer_counter
n’est jamais incrémenté. L’instruction qui incrémente ce compteur n’est jamais atteinte carBREAK OUTER
transfère le contrôle à la fin de la boucle externe.