FOR (Snowflakeスクリプト)

FOR ループは、特定の回数、一連のステップを繰り返します。回数は、ユーザーが指定することも、 カーソル の行数で指定することもできます。これら2種類の FOR ループの構文は少し異なります。

ループの詳細については、 ループの操作 をご参照ください。

注釈

この Snowflakeスクリプト 構造は、 Snowflakeスクリプトブロック 内でのみ有効です。

こちらもご参照ください

BREAKCONTINUE

構文

カーソル のすべての行をループするには、次を使用します。

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

指定された回数をループするには、次を使用します。

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

条件:

row_variable

オブジェクト識別子 の規則に従う変数名を指定します。

DECLARE または BEGIN ... END セクションにこの変数の宣言を追加しないでください。名前は、ローカルブロックのスコープでまだ定義されていないはずです。

名前は FOR ループの内側では有効ですが、 FOR ループの外側では無効です。

row_variable は、カーソルから1行を保持します。その行内のフィールドには、ドット表記を使用してアクセスします。例:

my_row_variable.my_column_name

より包括的な例は、以下の例に含まれています。

counter_variable

オブジェクト識別子 の規則に従う変数名を指定します。

counter_variable の名前は、 FOR ループ内でのみ有効です。同じ名前の変数がループの外側で宣言されている場合、外側の変数とループ変数は別々です。ループ内では、その名前への参照がループ変数に解決されます。

FOR ループ内のコードは、カウンター変数の値を読み取ることができますが、変更はしないでください。たとえば、ステップサイズを変更するためにカウンター変数を手動で増分しないでください。

start

これは、 counter_variable の初期値です。

開始値は、 INTEGER または INTEGER と評価される式である必要があります。

end

これは、ループ時に counter_variable が増分された後の、 counter_variable の最終値です。

終了値は、 INTEGER または INTEGER と評価される式である必要があります。

end の値は、 start の値以上である必要があります。 endstart 未満の場合、ループは0回実行されます(REVERSE キーワードが使用されている場合でも)。

statement

ステートメントは、次のいずれかになります。

  • 単一の SQL ステートメント(CALL を含む)。

  • 制御フローステートメント(例: ループ または 分岐 ステートメント)。

  • ネストされた ブロック

cursor_name

反復するカーソルの名前。

label

オプションのラベル。このようなラベルは、 BREAK (Snowflakeスクリプト) または CONTINUE (Snowflakeスクリプト) ステートメントのジャンプターゲットになる可能性があります。ラベルは、 オブジェクト識別子 の名前付け規則に従う必要があります。

使用上の注意

  • ループは、 end ポイントまで反復されます。

    たとえば、 FOR i IN 1 TO 10 は10回ループし、最後の反復では i の値は10です。

    REVERSE キーワードを使用すると、ループは start 値まで逆方向に反復されます。

  • ループには複数のステートメントを含めることができます。これらのステートメントを含めるために BEGIN ... END (Snowflakeスクリプト) ブロック を使用できますが、必須ではありません。

  • オプションのキーワード REVERSE を使用すると、Snowflakeは end の値で開始し、 start の値まで減分します。

  • ループ内で counter_variable の値を変更できますが、Snowflakeではこれを避けることをお勧めします。値を変更すると、コードが理解しにくくなります。

  • キーワード DO を使用する場合は、 FOR ループの最後で END FOR を使用します。キーワード LOOP を使用する場合は、 FOR ループの最後で END LOOP を使用します。

カーソルベースの FOR ループ

この例は、 カーソル を使用して、クエリによって返されるすべての行の price 列にある値を合計する方法を示しています。このストアドプロシージャは、集計関数のように動作します。

CREATE or replace TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
    (11.11),
    (22.22);
Copy
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;
$$
;
Copy

ストアドプロシージャの出力は次のとおりです。

CALL for_loop_over_cursor();
+----------------------+
| FOR_LOOP_OVER_CURSOR |
|----------------------|
|                33.33 |
+----------------------+
Copy
カウンターベースの FOR ループ

この例は、 FOR ループを使用して指定された回数を反復する方法を示しています。

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;
$$;
Copy

ストアドプロシージャの出力は次のとおりです。

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

次の例は、 REVERSE キーワードを使用して逆方向にカウントする方法を示しています。

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;
$$;
Copy

ストアドプロシージャの出力は次のとおりです。

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

次の例は、ループカウンター変数がすでに宣言されている変数と同じ名前(i)である場合の動作を示しています。 FOR ループ内では、 i への参照はループカウンター変数に解決されます(ループ外で宣言された変数には解決されません)。

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;
$$;
Copy

ストアドプロシージャの出力は次のとおりです。

CALL p(3);
+------------+
| P          |
|------------|
| counter: 3 |
| i: -999    |
+------------+
Copy