Às vezes, o loop tá indo de boa — até que aparece um motivo pra parar antes do fim. Ainda bem que o PL/pgSQL dá umas ferramentas bem práticas pra gente controlar isso.
Parando o loop com EXIT
Tem hora que você precisa terminar o loop antes dele chegar ao fim sozinho. Pode ser porque achou o valor que queria, rolou algum erro ou bateu numa condição que faz sentido parar. Nessas horas, a gente usa o EXIT.
EXIT é tipo falar pro loop: "Já deu, missão cumprida, pode parar".
A sintaxe do EXIT é super simples:
EXIT WHEN condição;
Aqui, a palavra-chave WHEN mostra em qual condição o loop vai ser interrompido. Se você não colocar condição, o EXIT simplesmente para o loop na hora.
Exemplo: parando o loop quando achar o valor certo
Imagina que a gente tem uma coluna com os números dos estudantes, e queremos achar um estudante com um ID específico. Assim que achar, o loop tem que parar.
DO $$
DECLARE
student_id INT;
BEGIN
FOR student_id IN 1..100 LOOP
RAISE NOTICE 'Verificando ID do estudante: %', student_id;
-- Se achou o estudante certo, para o loop
IF student_id = 42 THEN
RAISE NOTICE 'Estudante com ID 42 encontrado!';
EXIT;
END IF;
END LOOP;
END $$;
Nesse exemplo, o loop passa pelos números de 1 a 100, checando cada "estudante". Assim que o ID 42 aparece, ele mostra uma mensagem e para o loop.
Pulando iteração com CONTINUE
Tem situação que, dentro do loop, você quer pular algumas iterações, mas continuar rodando o resto. Isso é útil quando você quer ignorar dados "inúteis" ou pular passos pra condições específicas.
CONTINUE é tipo: "Beleza, essa condição não serve, bora pra próxima iteração".
CONTINUE funciona igual ao EXIT, só que ao invés de parar o loop, ele só pula a iteração atual:
CONTINUE WHEN condição;
Se a condição for verdadeira, ele termina a iteração e já vai pra próxima.
Exemplo: pulando números pares
Nesse exemplo, vamos passar pelos números de 1 a 10, mas ignorar os pares, mostrando só os ímpares.
DO $$
DECLARE
num INT;
BEGIN
FOR num IN 1..10 LOOP
-- Pulando números pares
IF num % 2 = 0 THEN
CONTINUE;
END IF;
RAISE NOTICE 'Número ímpar: %', num;
END LOOP;
END $$;
Aqui o CONTINUE pula todas as iterações onde num % 2 = 0 (ou seja, número par). No log, só vão aparecer os números ímpares.
Combinando EXIT e CONTINUE
Dá pra usar EXIT e CONTINUE juntos pra controlar o loop de um jeito mais flexível. Por exemplo, você pode pular iterações inúteis com CONTINUE, mas parar tudo se achar algo importante.
Olha esse exemplo: a gente pula todos os números múltiplos de 3, mas para o loop assim que chega no número 15.
DO $$
DECLARE
num INT;
BEGIN
FOR num IN 1..20 LOOP
-- Pulando números múltiplos de 3
IF num % 3 = 0 THEN
CONTINUE;
END IF;
-- Parando o loop se o número for 15
IF num = 15 THEN
RAISE NOTICE 'Parando no número %', num;
EXIT;
END IF;
RAISE NOTICE 'Número atual: %', num;
END LOOP;
END $$;
Aqui o loop funciona assim:
- Números múltiplos de 3 são pulados (
CONTINUE). - Se o número for 15, o loop para (
EXIT). - Todos os outros números são mostrados.
Exemplo avançado: pulando dados inválidos e parando em erro crítico
Agora imagina um caso mais real. Queremos processar uma lista de estudantes, checando os dados deles. Registros inválidos a gente pula, mas se rolar um "erro crítico", para tudo.
DO $$
DECLARE
student RECORD;
BEGIN
FOR student IN
SELECT * FROM students
LOOP
-- Pulando registros com dados inválidos
IF student.name IS NULL THEN
RAISE NOTICE 'Pulando estudante com ID %: Nome ausente', student.id;
CONTINUE;
END IF;
-- Parando o loop em caso de erro crítico
IF student.status = 'ERROR' THEN
RAISE EXCEPTION 'Erro crítico para estudante ID %', student.id;
EXIT; -- Essa linha é meio desnecessária, porque o RAISE EXCEPTION já para tudo.
END IF;
-- Processando o registro
RAISE NOTICE 'Processando estudante: %', student.name;
END LOOP;
END $$;
Nesse exemplo, o CONTINUE serve pra pular estudantes sem nome, e o EXIT (junto com RAISE EXCEPTION) para tudo se achar um erro sério.
Dicas práticas e erros comuns
Fica ligado na lógica das condições. Usar condições erradas dentro do EXIT WHEN ou CONTINUE WHEN pode dar uns bugs estranhos. Tipo, o loop pode acabar cedo demais ou pular dados importantes.
Cuidado com excesso de CONTINUE. Se seu código tá cheio de CONTINUE, talvez seja bom repensar a lógica do loop pra deixar mais simples.
Não confunde EXIT com RETURN. EXIT só para o loop atual, enquanto RETURN termina a função inteira.
Atenção com loops infinitos. Se você usar um loop LOOP sem uma condição clara pra parar, esquecer do EXIT pode fazer seu loop rodar pra sempre.
GO TO FULL VERSION