Loops permitem executar um bloco de código várias vezes seguidas, enquanto uma condição for verdadeira ou enquanto estiver iterando sobre algum conjunto de dados. Isso é super útil pra automatizar tarefas, processar grandes volumes de dados ou fazer operações repetitivas.
Imagina que você tem que dar balas pra todas as crianças de um grupo, uma por uma, na mão. Ia virar bagunça! Em vez disso, você pode passar pela lista das crianças e dar uma bala pra cada uma, na ordem. Nesse cenário, "passar pela lista" é um loop.
No PostgreSQL, tem vários tipos de loops:
LOOP— loop universal, roda até ser parado explicitamente.FOR— loop com número definido de iterações sobre um range de números ou resultado de uma query.WHILE— loop que roda enquanto a condição for verdadeira.
Bora ver cada tipo separadamente.
Loop infinito: LOOP
LOOP é a forma mais básica de loop em PL/pgSQL, que repete a execução de um bloco de código. Esse loop roda pra sempre, e você precisa finalizar ele manualmente usando o comando EXIT.
Sintaxe:
LOOP
-- Seu código aqui
END LOOP;
Vamos ver um exemplo. Vamos somar os números de 1 a 10 usando LOOP:
DO $$
DECLARE
counter INT := 1;
sum INT := 0;
BEGIN
LOOP
sum := sum + counter; -- adiciona o valor atual do contador
counter := counter + 1; -- incrementa o contador
-- Sai do loop se o contador for maior que 10
IF counter > 10 THEN
EXIT;
END IF;
END LOOP;
RAISE NOTICE 'Soma dos números de 1 a 10: %', sum;
END $$;
- A variável
counteré incrementada a cada iteração. - A condição
IF counter > 10 THEN EXIT;finaliza o loop quando o contador passa de 10. - No final, mostra a soma dos números.
Loop sobre range ou conjunto de dados: FOR
O segundo tipo de loop, FOR, é usado pra iterar sobre:
- Um range de números.
- O resultado de uma query SQL.
Loop sobre range de números
Sintaxe:
FOR variable IN [REVERSE] start..end LOOP
-- Seu código aqui
END LOOP;
Vamos mostrar os números de 1 a 5:
DO $$
BEGIN
FOR i IN 1..5 LOOP
RAISE NOTICE 'Valor atual: %', i;
END LOOP;
END $$;
Exemplo em ordem reversa:
DO $$
BEGIN
FOR i IN REVERSE 5..1 LOOP
RAISE NOTICE 'Ordem reversa: %', i;
END LOOP;
END $$;
Loop sobre resultado de query SQL
Esse jeito é útil pra processar linhas de uma tabela.
Sintaxe:
FOR variable IN QUERY (SELECT ...) LOOP
-- Seu código aqui
END LOOP;
Vamos ver um exemplo iterando sobre as linhas da tabela students:
DO $$
DECLARE
student_name TEXT;
BEGIN
FOR student_name IN QUERY (SELECT name FROM students) LOOP
RAISE NOTICE 'Oi, %!', student_name;
END LOOP;
END $$;
Loop condicional: WHILE
WHILE roda enquanto a condição for verdadeira.
Sintaxe:
WHILE condição LOOP
-- Seu código aqui
END LOOP;
Bora somar os números de 1 a 10 usando WHILE:
DO $$
DECLARE
counter INT := 1;
sum INT := 0;
BEGIN
WHILE counter <= 10 LOOP
sum := sum + counter;
counter := counter + 1;
END LOOP;
RAISE NOTICE 'Soma dos números de 1 a 10: %', sum;
END $$;
Exemplos da vida real
Agora que a gente já entendeu o básico dos loops, bora ver exemplos de uso deles.
Exemplo 1: gerando a tabuada
DO $$
DECLARE
i INT;
j INT;
BEGIN
FOR i IN 1..5 LOOP
FOR j IN 1..5 LOOP
RAISE NOTICE '% x % = %', i, j, i * j;
END LOOP;
END LOOP;
END $$;
Exemplo 2: iterando sobre resultados de query. Imagina que temos uma tabela products com os campos id e price. Vamos atualizar todos os preços, aumentando em 10%.
DO $$
DECLARE
prod RECORD;
BEGIN
FOR prod IN QUERY (SELECT id, price FROM products) LOOP
UPDATE products
SET price = prod.price * 1.1
WHERE id = prod.id;
END LOOP;
END $$;
Erros comuns e como evitar
Loop infinito em LOOP ou WHILE. Se você esquecer de colocar uma condição de saída (EXIT ou uma condição certa no WHILE), o loop nunca vai terminar. É tipo dirigir um carro sem freio.
Erro ao iterar sobre resultado de query. Se a estrutura dos dados retornados não for o que você espera, pode dar erro no loop FOR IN QUERY.
Queries não otimizadas dentro de loops. Por exemplo, rodar um UPDATE em cada iteração pode deixar tudo muito lento. Nesses casos, é melhor usar uma query SQL só, em vez de um loop.
GO TO FULL VERSION