ループの操作¶
Snowflakeスクリプトは、次のタイプのループをサポートしています。
このトピックでは、こうした各タイプのループの使用方法について説明します。
FOR ループ¶
FOR ループは、指定された回数、または結果セットの各行に対して一連のステップを繰り返します。Snowflakeスクリプトは、次のタイプの FOR ループをサポートします。
次のセクションでは、こうしたタイプの FOR ループの使用方法について説明します。
カウンターベースの FOR ループ¶
カウンターベースの FOR ループは、指定された回数を実行します。
カウンターベースの FOR ループの構文は次のとおりです。
FOR <counter_variable> IN [ REVERSE ] <start> TO <end> { DO | LOOP }
  <statement>;
  [ <statement>; ... ]
END { FOR | LOOP } [ <label> ] ;
例えば、次の FOR ループは5回実行されます。
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;
注意: Snowflake CLI、 SnowSQL、 Classic Console、 execute_stream、 execute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。
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;
$$
;
+-----------------+
| anonymous block |
|-----------------|
|               5 |
+-----------------+
Snowflake Scriptingのループ内に SQL ステートメントを含めることができます。例えば、次の FOR ループは、 INSERT ステートメントを5回実行し、カウンターの値をテーブルに挿入します。
DECLARE
  counter INTEGER DEFAULT 0;
  maximum_count INTEGER default 5;
BEGIN
  CREATE OR REPLACE TABLE test_for_loop_insert(i INTEGER);
  FOR i IN 1 TO maximum_count DO
    INSERT INTO test_for_loop_insert VALUES (:i);
    counter := counter + 1;
  END FOR;
  RETURN counter || ' rows inserted';
END;
注意: Snowflake CLI、 SnowSQL、 Classic Console、 execute_stream、 execute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。
EXECUTE IMMEDIATE $$
DECLARE
  counter INTEGER DEFAULT 0;
  maximum_count INTEGER default 5;
BEGIN
  CREATE OR REPLACE TABLE test_for_loop_insert(i INTEGER);
  FOR i IN 1 TO maximum_count DO
    INSERT INTO test_for_loop_insert VALUES (:i);
    counter := counter + 1;
  END FOR;
  RETURN counter || ' rows inserted';
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
| 5 rows inserted |
+-----------------+
テーブルをクエリして、挿入された行を表示します。
SELECT * FROM test_for_loop_insert;
+---+
| I |
|---|
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+---+
FOR ループの包括的な構文と詳細については、 FOR (Snowflakeスクリプト) をご参照ください。
カーソルベースの FOR ループ¶
カーソルベース の FOR ループは、結果セットを反復処理します。反復回数は、 カーソル の行数によって決まります。
カーソルベースの FOR ループの構文は次のとおりです。
FOR <row_variable> IN <cursor_name> DO
  <statement>;
  [ <statement>; ... ]
END FOR [ <label> ] ;
このセクションの例では、次の invoices テーブルのデータを使用しています。
CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
  (11.11),
  (22.22);
次の例では、 invoices テーブルのカーソル内の行を反復する FOR ループを使用しています。
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;
注意: Snowflake CLI、 SnowSQL、 Classic Console、 execute_stream、 execute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。
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;
$$
;
+-----------------+
| anonymous block |
|-----------------|
|           33.33 |
+-----------------+
FOR ループの包括的な構文と詳細については、 FOR (Snowflakeスクリプト) をご参照ください。
RESULTSET ベースの FOR ループ¶
RESULTSET ベースの FOR ループは、結果セットを反復処理します。反復回数は、 RESULTSET クエリによって返される行数によって決まります。
RESULTSET ベースの FOR ループの構文は次のとおりです。
FOR <row_variable> IN <RESULTSET_name> DO
  <statement>;
  [ <statement>; ... ]
END FOR [ <label> ] ;
このセクションの例では、次の invoices テーブルのデータを使用しています。
CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
  (11.11),
  (22.22);
次のブロックは、 FOR ループを使用して、 invoices テーブルの RESULTSET 内の行を反復処理します。
DECLARE
  total_price FLOAT;
  rs RESULTSET;
BEGIN
  total_price := 0.0;
  rs := (SELECT price FROM invoices);
  FOR record IN rs DO
    total_price := total_price + record.price;
  END FOR;
  RETURN total_price;
END;
注意: Snowflake CLI、 SnowSQL、 Classic Console、 execute_stream、 execute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。
EXECUTE IMMEDIATE $$
DECLARE
  total_price FLOAT;
  rs RESULTSET;
BEGIN
  total_price := 0.0;
  rs := (SELECT price FROM invoices);
  FOR record IN rs DO
    total_price := total_price + record.price;
  END FOR;
  RETURN total_price;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
|           33.33 |
+-----------------+
FOR ループの包括的な構文と詳細については、 FOR (Snowflakeスクリプト) をご参照ください。
WHILE ループ¶
WHILE ループは、条件がtrueの 間、反復されます。WHILE ループでは、ループの本文を実行する直前に条件がテストされます。最初の反復の前に条件がfalseの場合、ループの本文は1回も実行されません。
WHILE ループの構文は次のとおりです。
WHILE ( <condition> ) { DO | LOOP }
  <statement>;
  [ <statement>; ... ]
END { WHILE | LOOP } [ <label> ] ;
例:
BEGIN
  LET counter := 0;
  WHILE (counter < 5) DO
    counter := counter + 1;
  END WHILE;
  RETURN counter;
END;
注意: Snowflake CLI、 SnowSQL、 Classic Console、 execute_stream、 execute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。
EXECUTE IMMEDIATE $$
BEGIN
  LET counter := 0;
  WHILE (counter < 5) DO
    counter := counter + 1;
  END WHILE;
  RETURN counter;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
|               5 |
+-----------------+
WHILE ループの包括的な構文と詳細については、 WHILE (Snowflakeスクリプト) をご参照ください。
REPEAT ループ¶
REPEAT ループは、条件がtrueに なるまで 反復されます。REPEAT ループでは、ループの本文を実行した直後に条件がテストされます。その結果、ループの本文は常に少なくとも1回実行されます。
REPEAT ループの構文は次のとおりです。
REPEAT
  <statement>;
  [ <statement>; ... ]
UNTIL ( <condition> )
END REPEAT [ <label> ] ;
例:
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;
注意: Snowflake CLI、 SnowSQL、 Classic Console、 execute_stream、 execute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。
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;
$$
;
+-----------------+
| anonymous block |
|-----------------|
|               5 |
+-----------------+
REPEAT ループの包括的な構文と詳細については、 REPEAT (Snowflakeスクリプト) をご参照ください。
LOOP ループ¶
BREAK コマンドが実行されるまで、 LOOP ループは実行されます。BREAK コマンドは通常、分岐ロジック(例: IF ステートメント または CASE ステートメント)内に埋め込まれています。
LOOP ステートメントの構文は次のとおりです。
LOOP
  <statement>;
  [ <statement>; ... ]
END LOOP [ <label> ] ;
例:
BEGIN
  LET counter := 5;
  LOOP
    IF (counter = 0) THEN
      BREAK;
    END IF;
    counter := counter - 1;
  END LOOP;
  RETURN counter;
END;
注意: Snowflake CLI、 SnowSQL、 Classic Console、 execute_stream、 execute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。
EXECUTE IMMEDIATE $$
BEGIN
  LET counter := 5;
  LOOP
    IF (counter = 0) THEN
      BREAK;
    END IF;
    counter := counter - 1;
  END LOOP;
  RETURN counter;
END;
$$
;
+-----------------+
| anonymous block |
|-----------------|
|               0 |
+-----------------+
LOOP ループの包括的な構文と詳細については、 LOOP (Snowflakeスクリプト) をご参照ください。
ループまたは反復の終了¶
ループ構造では、ループまたはループの反復を早期に終了するときを指定できます。次のセクションでは、これについて詳しく説明します。
ループの終了¶
BREAK コマンドを実行すれば、ループを明示的に早期終了させることができます。BREAK (およびその同義語 EXIT)は、現在の反復を直ちに停止し、残りの反復をスキップします。BREAK は、ループ終了後にある最初の実行可能ステートメントにジャンプすると考えることができます。
BREAK は、 LOOP ループでは必要ですが、 WHILE、 FOR、および REPEAT ループでは必要ありません。ほとんどの場合、スキップするステートメントがあるときは、標準の分岐構造(IF ステートメント および CASE ステートメント)を使用して、ループ内のどのステートメントを実行するかを制御できます。
BREAK コマンド自体は通常、 IF または CASE ステートメント内にあります。
ループを終了せずに反復を終了¶
CONTINUE (または ITERATE)コマンドを使用して、ループの残りのステートメントをスキップして、ループの反復の最後にジャンプできます。ループは次の反復の開始時に続きます。
このようなジャンプが必要になることはめったにありません。ほとんどの場合、スキップするステートメントがあるときは、標準の分岐構造(IF ステートメント および CASE ステートメント)を使用して、ループ内のどのステートメントを実行するかを制御できます。
CONTINUE または ITERATE コマンド自体は、通常、 IF または CASE ステートメント内にあります。
終了後に実行を継続する場所の指定¶
BREAK または CONTINUE コマンドで、コード内の特定のポイント(例: ネストされたループの外側のループ)で実行を続行する必要がある場合は、実行を続行するポイントを識別するラベルを指定します。
次の例は、ネストされたループでこれを示しています。
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;
注意: Snowflake CLI、 SnowSQL、 Classic Console、 execute_stream、 execute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。
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;
$$;
この例では:
OUTER というラベルの付いたループにネストされた、 INNER というラベルの付いたループがあります。
CONTINUE OUTER は、ラベル OUTER があるループで別の反復を開始します。
BREAK OUTER は、内側のループを終了し、制御を外側のループ(OUTER のラベル付き)の最後に移します。
このコマンドの出力は次のとおりです。
+-----------------+
| anonymous block |
|-----------------|
| [               |
|   0,            |
|   5             |
| ]               |
+-----------------+
出力に示されているように、
inner_counterは5まで増加します。CONTINUE OUTER は、外側のループの新しい反復を開始します。これにより、内側のループの新しい反復が開始され、このカウンターは5まで増加します。これらの反復は、inner_counterの値が5になり、 BREAK OUTER が内部ループを終了するまで続きます。outer_counterが増加することはありません。このカウンターを増加するステートメントは、 BREAK OUTER が制御を外側のループの最後に移すため、このカウンターに到達することはありません。