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> ] ;
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;
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;
$$
;
+-----------------+
| 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> ] ;
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);
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;
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;
$$
;
+-----------------+
| 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> ] ;
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);
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;
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;
$$
;
+-----------------+
| 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> ] ;
Por exemplo:
BEGIN
LET counter := 0;
WHILE (counter < 5) DO
counter := counter + 1;
END WHILE;
RETURN counter;
END;
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;
$$
;
+-----------------+
| 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> ] ;
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;
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;
$$
;
+-----------------+
| 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> ] ;
Por exemplo:
BEGIN
LET counter := 5;
LOOP
IF (counter = 0) THEN
BREAK;
END IF;
counter := counter - 1;
END LOOP;
RETURN counter;
END;
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;
$$
;
+-----------------+
| 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;
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;
$$;
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 deinner_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.