Como trabalhar com loops

O Script Snowflake oferece suporte para os seguintes tipos de loops:

Este tópico explica como usar cada um desses tipos de loops.

Loop FOR

Um loop FOR repete uma sequência de passos por um número especificado de vezes ou para cada linha em um conjunto de resultados. O Script Snowflake oferece suporte para os seguintes tipos de loops FOR:

As próximas seções explicam como utilizar esses tipos de loops FOR.

Loops FOR baseados em contador

Um loop FOR baseado em contador é executado um número especificado de vezes.

A sintaxe para um loop FOR baseado no contador é

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

Por exemplo, o seguinte loop FOR é executado 5 vezes:

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

Observação: se você estiver usando o método SnowSQL, o Classic Console, execute_stream ou execute_string no código Python Connector, use este exemplo (consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python):

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;
$$
;
Copy
+-----------------+
| anonymous block |
|-----------------|
|               5 |
+-----------------+

Para obter a sintaxe completa e detalhes sobre loops FOR, consulte FOR (Script Snowflake).

Loops FOR baseados em cursor

Um loop FOR baseado em cursor itera sobre um conjunto de resultados. O número de iterações é determinado pelo número de linhas no cursor.

A sintaxe para um loop FOR baseado em cursor é:

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

O exemplo desta seção usa os dados da seguinte tabela invoices:

CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
  (11.11),
  (22.22);
Copy

O exemplo a seguir usa um loop FOR para iterar sobre as linhas em um cursor para a tabela invoices:

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

Observação: se você estiver usando o método SnowSQL, o Classic Console, execute_stream ou execute_string no código Python Connector, use este exemplo (consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python):

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;
$$
;
Copy
+-----------------+
| anonymous block |
|-----------------|
|           33.33 |
+-----------------+

Para obter a sintaxe completa e detalhes sobre loops FOR, consulte FOR (Script Snowflake).

Loops FOR baseados em RESULTSET

O loop FOR baseado em RESULTSET itera sobre um conjunto de resultados. O número de iterações é determinado pelo número de linhas retornadas pela consulta RESULTSET.

A sintaxe de um loop FOR baseado em RESULTSET é:

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

O exemplo desta seção usa os dados da seguinte tabela invoices:

CREATE OR REPLACE TABLE invoices (price NUMBER(12, 2));
INSERT INTO invoices (price) VALUES
  (11.11),
  (22.22);
Copy

O bloco a seguir usa um loop FOR para iterar sobre as linhas em um RESULTSET para a tabela invoices:

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

Observação: se você estiver usando o método SnowSQL, o Classic Console, execute_stream ou execute_string no código Python Connector, use este exemplo (consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python):

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;
$$
;
Copy
+-----------------+
| anonymous block |
|-----------------|
|           33.33 |
+-----------------+

Para obter a sintaxe completa e detalhes sobre loops FOR, consulte FOR (Script Snowflake).

Loop WHILE

Um loop WHILE itera enquanto a condição for verdadeira. Em um loop WHILE, a condição é testada imediatamente antes de executar o corpo do loop. Se a condição for falsa antes da primeira iteração, o corpo do loop não é executado nem mesmo uma vez.

A sintaxe de um loop WHILE é:

WHILE ( <condition> ) { DO | LOOP }
  <statement>;
  [ <statement>; ... ]
END { WHILE | LOOP } [ <label> ] ;
Copy

Por exemplo:

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

Observação: se você estiver usando o método SnowSQL, o Classic Console, execute_stream ou execute_string no código Python Connector, use este exemplo (consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python):

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

Para obter a sintaxe completa e detalhes sobre loops WHILE, consulte WHILE (Script Snowflake).

Loop REPEAT

Um loop REPEAT itera até uma condição ser verdadeira. Em um loop REPEAT, a condição é testada imediatamente após a execução do corpo do loop. Como resultado, o corpo do loop sempre é executado pelo menos uma vez.

A sintaxe de um loop REPEAT é:

REPEAT
  <statement>;
  [ <statement>; ... ]
UNTIL ( <condition> )
END REPEAT [ <label> ] ;
Copy

Por exemplo:

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

Observação: se você estiver usando o método SnowSQL, o Classic Console, execute_stream ou execute_string no código Python Connector, use este exemplo (consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python):

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;
$$
;
Copy
+-----------------+
| anonymous block |
|-----------------|
|               5 |
+-----------------+

Para obter a sintaxe completa e detalhes sobre loops REPEAT, consulte REPEAT (Script Snowflake).

Loop LOOP

Um loop LOOP é executado até que um comando BREAK seja executado. Um comando BREAK normalmente é incorporado dentro da lógica de ramificação (por exemplo, Instruções IF ou Instruções CASE).

A sintaxe para uma instrução LOOP é:

LOOP
  <statement>;
  [ <statement>; ... ]
END LOOP [ <label> ] ;
Copy

Por exemplo:

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

Observação: se você estiver usando o método SnowSQL, o Classic Console, execute_stream ou execute_string no código Python Connector, use este exemplo (consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python):

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

Para obter a sintaxe completa e detalhes sobre loops LOOP, consulte LOOP (Script Snowflake).

Encerramento de um loop ou iteração

Em uma construção de loop, você pode especificar quando o loop ou uma iteração do loop deve terminar mais cedo. As próximas seções explicam isso com mais detalhes:

Encerramento de um loop

Você pode encerrar explicitamente um loop antecipadamente executando o comando BREAK. BREAK (e seu sinônimo EXIT) interrompe imediatamente a iteração atual e ignora quaisquer iterações restantes. Você pode pensar em BREAK como um salto para a primeira instrução executável após o final do loop.

BREAK é necessário em um loop LOOP, mas não é necessário em loops WHILE, FOR e REPEAT. Na maioria dos casos, se você tem instruções que deseja pular, você pode usar as construções de ramificação padrão (Instruções IF e Instruções CASE) para controlar quais instruções dentro de um loop serão executadas.

Um comando BREAK em si normalmente está dentro de uma instrução IF ou CASE.

Como encerrar uma iteração sem encerrar o loop

Você pode usar o comando CONTINUE (ou ITERATE) para pular para o final de uma iteração de um loop, pulando as instruções restantes no loop. O loop continua no início da próxima iteração.

Tais saltos raramente são necessários. Na maioria dos casos, se você tem instruções que deseja pular, você pode usar as construções de ramificação padrão (Instruções IF e Instruções CASE) para controlar quais instruções dentro de um loop serão executadas.

Um comando CONTINUE ou ITERATE normalmente está dentro de uma instrução IF ou CASE.

Como especificar onde a execução deve continuar após o término

Em um comando BREAK ou CONTINUE, se você precisar continuar a execução em um ponto específico do código (por exemplo, o loop externo em um loop aninhado), especifique uma etiqueta que identifique o ponto em que a execução deve continuar.

O exemplo a seguir demonstra isso em um loop aninhado:

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

Observação: se você estiver usando o método SnowSQL, o Classic Console, execute_stream ou execute_string no código Python Connector, use este exemplo (consulte Uso do Script Snowflake em SnowSQL, Classic Console e conector Python):

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

Neste exemplo:

  • Há um loop com a etiqueta INNER que está aninhado em um loop com a etiqueta OUTER.

  • CONTINUE OUTER inicia outra iteração do loop com a etiqueta OUTER.

  • BREAK OUTER encerra o loop interno e transfere o controle para o final do loop externo (com a etiqueta OUTER).

A saída desse comando é:

+-----------------+
| anonymous block |
|-----------------|
| [               |
|   0,            |
|   5             |
| ]               |
+-----------------+

Como mostrado na saída:

  • inner_counter é incrementado até 5. CONTINUE OUTER inicia uma nova iteração do loop externo, que inicia uma nova iteração do loop interno, que incrementa esse contador até 5. Essas iterações continuam até que o valor de inner_counter seja igual a 5 e BREAK OUTER termina o loop interno.

  • outer_counter nunca é incrementado. A instrução que aumenta esse contador nunca é alcançada porque BREAK OUTER transfere o controle para o final do loop externo.