FOR (Script Snowflake)¶
Um loop FOR
repete uma sequência de etapas por um número específico de vezes. O número de vezes pode ser especificado pelo usuário, ou pode ser especificado pelo número de linhas em um cursor. A sintaxe destes dois tipos de loops FOR
é um pouco diferente.
Para obter mais informações sobre loops, consulte Como trabalhar com loops.
Nota
Este constructo do Script Snowflake só é válido dentro de um bloco do Script Snowflake.
Sintaxe¶
Para fazer o loop sobre todas as linhas em um cursor, use:
FOR <row_variable> IN <cursor_name> DO statement; [ statement; ... ] END FOR [ <label> ] ;
Para fazer o loop um número especificado de vezes, use:
FOR <counter_variable> IN [ REVERSE ] <start> TO <end> { DO | LOOP } statement; [ statement; ... ] END { FOR | LOOP } [ <label> ] ;
Onde:
row_variable
Especifique um nome de variável que siga as regras para Identificadores de objetos.
Não adicionar uma instrução para esta variável em DECLARE ou BEGIN … END …. O nome ainda não deve ser definido no âmbito do bloco local.
O nome é válido dentro do loop
FOR
, mas não fora do loopFOR
.O
row_variable
mantém uma linha a partir do cursor. Os campos dentro dessa linha são acessados usando a notação de pontos. Por exemplo:
my_row_variable.my_column_name
Um exemplo mais completo está incluído nos exemplos abaixo.
counter_variable
Especifique um nome de variável que siga as regras para Identificadores de objetos.
O nome do
counter_variable
é válido somente dentro do loopFOR
. Se uma variável com o mesmo nome for declarada fora do loop, a variável externa e a variável do loop são separadas. Dentro do loop, as referências a esse nome são resolvidas para a variável do loop.O código dentro do loop
FOR
é permitido para ler o valor da variável de contador, mas não deve alterá-lo. Por exemplo, não aumente a variável de contador manualmente para alterar o tamanho da etapa.start
Este é o valor inicial de
counter_variable
.O valor inicial deve ser um INTEGER ou uma expressão que é avaliada como um INTEGER.
end
Este é o valor final de
counter_variable
, após ocounter_variable
ter sido incrementado à medida que você faz o loop.O valor final deve ser um INTEGER ou uma expressão que é avaliada como um INTEGER.
O valor
end
deve ser maior ou igual ao valorstart
. Seend
for menor questart
, o loop executa 0 vezes (mesmo que a palavra-chaveREVERSE
seja usada).
statement
Uma instrução pode ser qualquer uma das seguintes opções:
Uma única instrução SQL (incluindo CALL).
Uma instrução de fluxo de controle (ex.: instrução de looping ou ramificação).
Um bloco aninhado.
cursor_name
O nome do cursor para iterar.
label
Uma tag opcional. Tal tag pode ser um destino de salto para uma instrução BREAK (Script Snowflake) ou CONTINUE (Script Snowflake). Uma tag deve seguir as regras de nomenclatura para Identificadores de objetos.
Notas de uso¶
O loop itera até e incluindo o ponto
end
.Por exemplo,
FOR i IN 1 TO 10
faz o loop 10 vezes, e durante a iteração final o valor dei
é 10.Se você usar a palavra-chave
REVERSE
, então a iteração do loop retrocede até e incluindo o valorstart
.Um loop pode conter múltiplas instruções. Você pode usar, mas não é obrigatório, um BEGIN … END (Script Snowflake) bloco para conter essas instruções.
A palavra-chave opcional
REVERSE
faz com que o Snowflake comece com o valorend
e decresça até o valorstart
.Embora você possa alterar o valor do
counter_variable
dentro do loop, o Snowflake recomenda que você evite fazer isso. A alteração do valor torna o código mais difícil de entender.Se você usar a palavra-chave
DO
, então useEND FOR
no fim do loopFOR
. Se você usar a palavra-chaveLOOP
, então useEND LOOP
no fim do loopFOR
.
Exemplos¶
- Loops FOR baseados em cursor:
Este exemplo mostra como usar um cursor para somar os valores na price
coluna de todas as linhas retornadas por uma consulta. Este procedimento armazenado comporta-se de certa forma como uma função agregada.
CREATE or replace TABLE invoices (price NUMBER(12, 2)); INSERT INTO invoices (price) VALUES (11.11), (22.22);CREATE OR REPLACE PROCEDURE for_loop_over_cursor() RETURNS FLOAT LANGUAGE SQL AS $$ DECLARE total_price FLOAT; c1 CURSOR FOR SELECT price FROM invoices; BEGIN total_price := 0.0; OPEN c1; FOR rec IN c1 DO total_price := total_price + rec.price; END FOR; CLOSE c1; RETURN total_price; END; $$ ;Aqui está a saída do procedimento armazenado:
CALL for_loop_over_cursor(); +----------------------+ | FOR_LOOP_OVER_CURSOR | |----------------------| | 33.33 | +----------------------+
- Loops FOR baseados em contador:
Este exemplo mostra como usar um loop FOR
para iterar um número especificado de vezes:
CREATE PROCEDURE simple_for(iteration_limit INTEGER) RETURNS INTEGER LANGUAGE SQL AS $$ DECLARE counter INTEGER DEFAULT 0; BEGIN FOR i IN 1 TO iteration_limit DO counter := counter + 1; END FOR; RETURN counter; END; $$;Aqui está a saída do procedimento armazenado:
CALL simple_for(3); +------------+ | SIMPLE_FOR | |------------| | 3 | +------------+
O exemplo a seguir mostra como usar a palavra-chave REVERSE
para a contagem regressiva.
CREATE PROCEDURE reverse_loop(iteration_limit INTEGER) RETURNS VARCHAR LANGUAGE SQL AS $$ DECLARE values_of_i VARCHAR DEFAULT ''; BEGIN FOR i IN REVERSE 1 TO iteration_limit DO values_of_i := values_of_i || ' ' || i::varchar; END FOR; RETURN values_of_i; END; $$;Aqui está a saída do procedimento armazenado:
CALL reverse_loop(3); +--------------+ | REVERSE_LOOP | |--------------| | 3 2 1 | +--------------+
O exemplo seguinte mostra o comportamento quando a variável do contador de loop tem o mesmo nome (i
) que uma variável que já foi declarada. Dentro do loop FOR
, as referências a i
resolvem para a variável do contador do loop (não para a variável declarada fora do loop).
CREATE PROCEDURE p(iteration_limit INTEGER) RETURNS VARCHAR LANGUAGE SQL AS $$ DECLARE counter INTEGER DEFAULT 0; i INTEGER DEFAULT -999; return_value VARCHAR DEFAULT ''; BEGIN FOR i IN 1 TO iteration_limit DO counter := counter + 1; END FOR; return_value := 'counter: ' || counter::varchar || '\n'; return_value := return_value || 'i: ' || i::VARCHAR; RETURN return_value; END; $$;Aqui está a saída do procedimento armazenado:
CALL p(3); +------------+ | P | |------------| | counter: 3 | | i: -999 | +------------+