ループの操作

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;

注: SnowSQL または 従来のウェブインターフェイス を使用している場合は、代わりに次の例を使用します(SnowSQL でのSnowflakeスクリプトと従来のウェブインターフェイスの使用 を参照)。

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

FOR ステートメントの包括的な構文と詳細については、 FOR をご参照ください。

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

カーソルベースFOR ループは、結果セットを反復処理します。反復回数は、 カーソル の行数によって決まります。

カーソルベースの FOR ループの構文は次のとおりです。

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

次の例では、 invoices テーブルのカーソル内の行を反復する FOR ループを使用しています。

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;

注: SnowSQL または 従来のウェブインターフェイス を使用している場合は、代わりに次の例を使用します(SnowSQL でのSnowflakeスクリプトと従来のウェブインターフェイスの使用 を参照)。

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

FOR ステートメントの包括的な構文と詳細については、 FOR をご参照ください。

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;

注: SnowSQL または 従来のウェブインターフェイス を使用している場合は、代わりに次の例を使用します(SnowSQL でのSnowflakeスクリプトと従来のウェブインターフェイスの使用 を参照)。

EXECUTE IMMEDIATE $$
BEGIN
  LET counter := 0;
  WHILE (counter < 5) DO
    counter := counter + 1;
  END WHILE;
  RETURN counter;
END;
$$
;

WHILE ステートメントの包括的な構文と詳細については、 WHILE をご参照ください。

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;

注: SnowSQL または 従来のウェブインターフェイス を使用している場合は、代わりに次の例を使用します(SnowSQL でのSnowflakeスクリプトと従来のウェブインターフェイスの使用 を参照)。

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

REPEAT ステートメントの包括的な構文と詳細については、 REPEAT をご参照ください。

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;

注: SnowSQL または 従来のウェブインターフェイス を使用している場合は、代わりに次の例を使用します(SnowSQL でのSnowflakeスクリプトと従来のウェブインターフェイスの使用 を参照)。

EXECUTE IMMEDIATE $$
BEGIN
  LET counter := 5;
  LOOP
    IF (counter = 0) THEN
      BREAK;
    END IF;
    counter := counter - 1;
  END LOOP;
  RETURN counter;
END;
$$
;

LOOP ステートメントの包括的な構文と詳細については、 LOOP をご参照ください。

ループまたは反復の終了

ループ構造では、ループまたはループの反復を早期に終了するときを指定できます。次のセクションでは、これについて詳しく説明します。

ループの終了

BREAK コマンドを実行することにより、ループを早期に明示的に終了できます。 BREAK (およびその同義語 EXIT)は、現在の反復を即座に停止し、残りの反復をスキップします。 BREAK は、ループ終了後にある最初の実行可能ステートメントにジャンプすると考えることができます。

BREAK は、 LOOP では必要ですが、 WHILEFOR、および 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;

注: SnowSQL または 従来のウェブインターフェイス を使用している場合は、代わりに次の例を使用します(SnowSQL でのSnowflakeスクリプトと従来のウェブインターフェイスの使用 を参照)。

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まで増加します。

  • outer_counter が増加することはありません。このカウンターを増加するステートメントは、 BREAK OUTER が制御を外側のループの最後に移すため、このカウンターに到達することはありません。

最上部に戻る