FOR

Une boucle FOR répète une séquence d’étapes un nombre spécifique de fois. Le nombre de fois peut être spécifié par l’utilisateur, ou peut être spécifié par le nombre de lignes dans un curseur. La syntaxe de ces deux types de boucles FOR est légèrement différente.

Pour plus d’informations sur les boucles, voir Travailler avec des boucles.

Voir aussi

BREAK, CONTINUE

Syntaxe

Pour boucler sur toutes les lignes d’un curseur, utilisez :

FOR <row_variable> IN <cursor_name> DO
    statement;
    [ statement; ... ]
END FOR [ <label> ] ;

Pour boucler un nombre précis de fois, utilisez :

FOR <counter_variable> IN [ REVERSE ] <start> TO <end> { DO | LOOP }
    statement;
    [ statement; ... ]
END { FOR | LOOP } [ <label> ] ;

Où :

row_variable

Spécifiez un nom de variable qui suit les règles pour Identificateurs d’objet.

N’ajoutez pas de déclaration pour cette variable dans les sections DECLARE ou BEGIN … END. Le nom ne doit pas être déjà défini dans le scope du bloc local.

Le nom est valide à l’intérieur de la boucle FOR, mais pas à l’extérieur de la boucle FOR.

La row_variable contient une ligne du curseur. Les champs de cette ligne sont accessibles en utilisant la notation par points. Par exemple :

my_row_variable.my_column_name

Un exemple plus complet est inclus dans les exemples ci-dessous.

counter_variable

Spécifiez un nom de variable qui suit les règles pour Identificateurs d’objet.

Le nom de la variable counter_variable n’est valable qu’à l’intérieur de la boucle FOR. Si une variable portant le même nom est déclarée en dehors de la boucle, la variable externe et la variable de la boucle sont distinctes. Dans la boucle, les références à ce nom sont résolues dans la variable de la boucle.

Le code à l’intérieur de la boucle FOR est autorisé à lire la valeur de la variable compteur, mais ne doit pas la modifier. Par exemple, n’incrémentez pas la variable compteur manuellement pour modifier la taille d’incrémentation.

start

C’est la valeur initiale de counter_variable.

La valeur de départ doit être un INTEGER ou une expression qui donne un INTEGER.

end

C’est la valeur finale de counter_variable, après que la counter_variable a été incrémentée au fur et à mesure de la boucle.

La valeur finale doit être un INTEGER ou une expression qui donne un INTEGER.

La valeur end doit être supérieure ou égale à la valeur start. Si end est inférieur à start, la boucle s’exécute 0 fois (même si le mot-clé REVERSE est utilisé).

statement

Une instruction peut être l’un des éléments suivants :

  • Une seule instruction SQL (y compris CALL).

  • Une instruction de flux de contrôle (par exemple, instruction looping ou branching).

  • Un bloc imbriqué.

cursor_name

Le nom du curseur à itérer.

label

Une étiquette facultative. Une telle étiquette peut être une cible de saut pour une instruction BREAK ou CONTINUE. Une étiquette doit respecter les règles de dénomination de Identificateurs d’objet.

Notes sur l’utilisation

  • La boucle itère jusqu’au point end inclus.

    Par exemple, FOR i IN 1 TO 10 boucle 10 fois, et lors de la dernière itération, la valeur de i est 10.

    Si vous utilisez le mot-clé REVERSE, la boucle itère alors en sens inverse jusqu’à la valeur start incluse.

  • Une boucle peut contenir plusieurs instructions. Vous pouvez utiliser, sans y être obligé, un BEGIN … END bloc pour contenir ces instructions.

  • Le mot-clé facultatif REVERSE fait que Snowflake commence par la valeur end et décrémente jusqu’à la valeur start.

  • Bien que vous puissiez modifier la valeur de la variable counter_variable à l’intérieur de la boucle, Snowflake vous recommande d’éviter de le faire. Changer la valeur rend le code plus difficile à comprendre.

  • Si vous utilisez le mot-clé DO, alors utilisez END FOR à la fin de la boucle FOR. Si vous utilisez le mot-clé LOOP, alors utilisez END LOOP à la fin de la boucle FOR.

Exemples

Boucles FOR basées sur le curseur

Cet exemple montre comment utiliser un curseur pour additionner les valeurs de la colonne price de toutes les lignes retournées par une requête. Cette procédure stockée se comporte un peu comme une fonction d’agrégation.

CREATE or replace TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
    (11.11),
    (22.22);
CREATE OR REPLACE PROCEDURE for_loop_over_cursor()
RETURNS FLOAT
LANGUAGE SQL
AS
$$
DECLARE
    total_price FLOAT;
    c1 CURSOR FOR SELECT price FROM invoices;
BEGIN
    total_price := 0.0;
    OPEN c1;
    FOR rec IN c1 DO
        total_price := total_price + rec.price;
    END FOR;
    CLOSE c1;
    RETURN total_price;
END;
$$
;

Voici la sortie de la procédure stockée :

CALL for_loop_over_cursor();
+----------------------+
| FOR_LOOP_OVER_CURSOR |
|----------------------|
|                33.33 |
+----------------------+
Boucles FOR basées sur le compteur

Cet exemple montre comment utiliser une boucle FOR pour itérer un nombre spécifié de fois :

CREATE PROCEDURE simple_for(iteration_limit INTEGER)
RETURNS INTEGER
LANGUAGE SQL
AS
$$
    DECLARE
        counter INTEGER DEFAULT 0;
    BEGIN
        FOR i IN 1 TO iteration_limit DO
            counter := counter + 1;
        END FOR;
        RETURN counter;
    END;
$$;

Voici la sortie de la procédure stockée :

CALL simple_for(3);
+------------+
| SIMPLE_FOR |
|------------|
|          3 |
+------------+

Cet exemple montre comment utiliser le mot-clé REVERSE pour compter en arrière.

CREATE PROCEDURE reverse_loop(iteration_limit INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
    DECLARE
        values_of_i VARCHAR DEFAULT '';
    BEGIN
        FOR i IN REVERSE 1 TO iteration_limit DO
            values_of_i := values_of_i || ' ' || i::varchar;
        END FOR;
        RETURN values_of_i;
    END;
$$;

Voici la sortie de la procédure stockée :

CALL reverse_loop(3);
+--------------+
| REVERSE_LOOP |
|--------------|
|  3 2 1       |
+--------------+

L’exemple suivant montre le comportement lorsque la variable du compteur de boucle a le même nom (i) qu’une variable déjà déclarée. Dans la boucle FOR, les références à i se résolvent dans la variable du compteur de la boucle (et non dans la variable déclarée en dehors de la boucle).

CREATE PROCEDURE p(iteration_limit INTEGER)
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
    DECLARE
        counter INTEGER DEFAULT 0;
        i INTEGER DEFAULT -999;
        return_value VARCHAR DEFAULT '';
    BEGIN
        FOR i IN 1 TO iteration_limit DO
            counter := counter + 1;
        END FOR;
        return_value := 'counter: ' || counter::varchar || '\n';
        return_value := return_value || 'i: ' || i::VARCHAR;
        RETURN return_value;
    END;
$$;

Voici la sortie de la procédure stockée :

CALL p(3);
+------------+
| P          |
|------------|
| counter: 3 |
| i: -999    |
+------------+
Revenir au début