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.

Consulte também:

BREAK, CONTINUE

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

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

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 loop FOR.

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 loop FOR. 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 o counter_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 valor start. Se end for menor que start, o loop executa 0 vezes (mesmo que a palavra-chave REVERSE 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 de i é 10.

    Se você usar a palavra-chave REVERSE, então a iteração do loop retrocede até e incluindo o valor start.

  • 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 valor end e decresça até o valor start.

  • 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 use END FOR no fim do loop FOR. Se você usar a palavra-chave LOOP, então use END LOOP no fim do loop FOR.

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

Aqui está a saída do procedimento armazenado:

CALL for_loop_over_cursor();
+----------------------+
| FOR_LOOP_OVER_CURSOR |
|----------------------|
|                33.33 |
+----------------------+
Copy
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;
$$;
Copy

Aqui está a saída do procedimento armazenado:

CALL simple_for(3);
+------------+
| SIMPLE_FOR |
|------------|
|          3 |
+------------+
Copy

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

Aqui está a saída do procedimento armazenado:

CALL reverse_loop(3);
+--------------+
| REVERSE_LOOP |
|--------------|
|  3 2 1       |
+--------------+
Copy

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

Aqui está a saída do procedimento armazenado:

CALL p(3);
+------------+
| P          |
|------------|
| counter: 3 |
| i: -999    |
+------------+
Copy