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