Análise dos erros mais comuns ao trabalhar com estruturas de controle e logging
Indo direto ao ponto, bora falar dos erros e mancadas mais comuns que você pode encontrar. Porque erro em SQL é dor de cabeça pra qualquer dev, e normalmente aparece na pior hora possível.
1. Erros de sintaxe: "esqueci de fechar o IF"
Erros de sintaxe são os mais básicos, mas acontecem mais do que você imagina. Por exemplo, se você esquece de fechar um bloco condicional IF com END IF;, o compilador já vai te julgar na hora.
Exemplo de erro:
CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN 'Positivo';
ELSE
RETURN 'Negativo';
-- em algum lugar sumiu o END IF;
END;
$$ LANGUAGE plpgsql;
Quando você tentar rodar esse código, vai receber o erro: ERROR: syntax error at or near "END". Por quê? Porque o bloco IF ficou aberto.
Como evitar esse tipo de erro?
Sempre mantenha a estrutura do código certinha. Abriu um bloco (tipo IF), já escreve o fechamento dele. Olha o exemplo corrigido:
CREATE OR REPLACE FUNCTION check_number(num INTEGER)
RETURNS TEXT AS $$
BEGIN
IF num > 0 THEN
RETURN 'Positivo';
ELSE
RETURN 'Negativo';
END IF; -- não esquece de fechar o bloco
END;
$$ LANGUAGE plpgsql;
2. Esqueceu de tratar todos os casos no CASE: "E se não cair em nenhum?"
Quando você usa CASE, sempre coloca um ELSE pra tratar situações inesperadas. Se não tiver esse ramo, pode acabar retornando NULL sem querer.
Exemplo de erro:
CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
RETURN CASE grade
WHEN 'A' THEN 'Excelente'
WHEN 'B' THEN 'Bom'
WHEN 'C' THEN 'Médio'
-- E se grade = 'D' ou outra nota?
END;
END;
$$ LANGUAGE plpgsql;
Se você passar o valor D, a função vai retornar NULL, o que pode dar ruim no seu código.
Versão corrigida:
CREATE OR REPLACE FUNCTION grade_result(grade CHAR)
RETURNS TEXT AS $$
BEGIN
RETURN CASE grade
WHEN 'A' THEN 'Excelente'
WHEN 'B' THEN 'Bom'
WHEN 'C' THEN 'Médio'
ELSE 'Nota desconhecida' -- Pegando todos os outros casos
END;
END;
$$ LANGUAGE plpgsql;
3. Problemas com loops infinitos: "Por que o servidor travou?"
Usando o loop LOOP, é fácil esquecer de colocar uma condição de saída. Isso pode causar execução infinita:
Exemplo de erro:
CREATE OR REPLACE FUNCTION infinite_loop_demo()
RETURNS VOID AS $$
DECLARE
i INTEGER := 1;
BEGIN
LOOP
i := i + 1;
-- Não tem condição de saída!
END LOOP;
END;
$$ LANGUAGE plpgsql;
Esse código vai travar o servidor porque o loop nunca termina.
Como corrigir:
Coloca uma condição de saída usando EXIT:
CREATE OR REPLACE FUNCTION finite_loop_demo()
RETURNS VOID AS $$
DECLARE
i INTEGER := 1;
BEGIN
LOOP
i := i + 1;
IF i > 10 THEN
EXIT; -- Condição de saída
END IF;
END LOOP;
END;
$$ LANGUAGE plpgsql;
4. Pulando iterações no loop: "E os dados que faltaram?"
Quando você usa CONTINUE pra pular iterações, pode dar ruim se não pensar em todos os cenários. Por exemplo:
Exemplo de erro:
CREATE OR REPLACE FUNCTION skip_even()
RETURNS VOID AS $$
DECLARE
i INTEGER := 0;
BEGIN
WHILE i < 10 LOOP
i := i + 1;
IF i % 2 = 0 THEN
CONTINUE; -- Só pula os pares
END IF;
RAISE NOTICE 'Número ímpar: %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
E se todos os números forem pares? O servidor vai rodar, mas você não vai ver resultado nenhum.
Como corrigir:
Garante que todos os dados são tratados certinho e adiciona logs pra acompanhar:
CREATE OR REPLACE FUNCTION skip_even_logging()
RETURNS VOID AS $$
DECLARE
i INTEGER := 0;
BEGIN
WHILE i < 10 LOOP
i := i + 1;
IF i % 2 = 0 THEN
RAISE NOTICE 'Pulando número par: %', i;
CONTINUE;
END IF;
RAISE NOTICE 'Número ímpar: %', i;
END LOOP;
END;
$$ LANGUAGE plpgsql;
Agora você vê quais números foram pulados.
5. Tratamento de erro errado: "Cadê meu RAISE EXCEPTION?"
Tratar erro com RAISE EXCEPTION é poderoso, mas pode dar ruim se usar errado.
Exemplo de erro:
CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
IF num < 0 THEN
RAISE 'Número negativo não é permitido!';
END IF;
RETURN num * num;
END;
$$ LANGUAGE plpgsql;
Esse código vai dar erro porque a sintaxe do RAISE tá errada (faltou o nível da mensagem).
Versão corrigida:
CREATE OR REPLACE FUNCTION calculate_square(num INTEGER)
RETURNS INTEGER AS $$
BEGIN
IF num < 0 THEN
RAISE EXCEPTION 'Número negativo não é permitido!';
END IF;
RETURN num * num;
END;
$$ LANGUAGE plpgsql;
6. Erros ao fazer logging: "Por que meus erros não aparecem no error_log?"
Registrar errado na tabela error_log pode acontecer por erro no INSERT INTO.
Exemplo de erro:
CREATE OR REPLACE FUNCTION log_error(err_msg TEXT)
RETURNS VOID AS $$
BEGIN
INSERT INTO error_log (error_message, error_time)
VALUES (err_msg, CURRENT_TIMESTAMP); -- E se tiver erro nos nomes das colunas?
END;
$$ LANGUAGE plpgsql;
Se o nome da coluna na tabela error_log mudou (tipo pra error_msg), isso vai dar erro.
Como evitar:
Sempre confere a estrutura da tabela ou usa um schema bem definido pra controlar os dados.
7. Desatenção geral e "fator humano"
Os erros não são só técnicos, mas também de distração. Debug esquecido, variáveis não usadas ou falta de formatação podem transformar sua função numa bagunça.
Exemplo:
DECLARE
i INTEGER; -- Pra quê, se a variável não é usada?
Correção: tira as partes inúteis do código pra ele ficar limpo e fácil de entender.
Agora você tá pronto pra evitar os erros mais comuns em PL/pgSQL e escrever código que dá mais alegria do que dor de cabeça. Não esquece de testar, logar e corrigir bugs na hora certa — isso vai te poupar muito estresse e ligação de cliente!
GO TO FULL VERSION