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.
Neste tópico:
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;Nota: se você estiver usando SnowSQL ou Classic Console, use este exemplo (consulte Como usar o Script Snowflake no SnowSQL e na Classic Console):
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; $$ ;
Para obter a sintaxe completa e detalhes sobre instruções 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 a seguir usa um loop FOR para iterar sobre as linhas em um cursor para a tabela invoices
:
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;Nota: se você estiver usando SnowSQL ou Classic Console, use este exemplo (consulte Como usar o Script Snowflake no SnowSQL e na Classic Console):
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; $$ ;
Para obter a sintaxe completa e detalhes sobre instruções 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;Nota: se você estiver usando SnowSQL ou Classic Console, use este exemplo (consulte Como usar o Script Snowflake no SnowSQL e na Classic Console):
EXECUTE IMMEDIATE $$ BEGIN LET counter := 0; WHILE (counter < 5) DO counter := counter + 1; END WHILE; RETURN counter; END; $$ ;
Para obter a sintaxe completa e detalhes sobre instruções 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;Nota: se você estiver usando SnowSQL ou Classic Console, use este exemplo (consulte Como usar o Script Snowflake no SnowSQL e na Classic Console):
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; $$ ;
Para obter a sintaxe completa e detalhes sobre instruções REPEAT
, consulte REPEAT (Script Snowflake).
Loop LOOP¶
Um loop LOOP é executado até que um comando BREAK seja executado. Tal 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;Nota: se você estiver usando SnowSQL ou Classic Console, use este exemplo (consulte Como usar o Script Snowflake no SnowSQL e na Classic Console):
EXECUTE IMMEDIATE $$ BEGIN LET counter := 5; LOOP IF (counter = 0) THEN BREAK; END IF; counter := counter - 1; END LOOP; RETURN counter; END; $$ ;
Para obter a sintaxe completa e detalhes sobre instruções 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 pula 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
, mas não é necessário em 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 um 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 um 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;Nota: se você estiver usando SnowSQL ou Classic Console, use este exemplo (consulte Como usar o Script Snowflake no SnowSQL e na Classic Console):
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 etiquetaOUTER
.CONTINUE OUTER
inicia outra iteração do loop com a etiquetaOUTER
.BREAK OUTER
encerra o loop interno e transfere o controle para o final do loop externo (com a etiquetaOUTER
).
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.outer_counter
nunca é incrementado. A instrução que aumenta esse contador nunca é alcançada porqueBREAK OUTER
transfere o controle para o final do loop externo.