Imagina que você tá escrevendo uma função que calcula a média das notas de um estudante. O que acontece se tentar dividir por zero (tipo, se não tiver nenhuma nota)? Se você tentar rodar esse código na vida real — o erro vai aparecer rapidinho. O PL/pgSQL tem ferramentas poderosas pra tratar esses erros, deixando seu código mais robusto, seguro e tranquilo de mexer.
O tratamento de erros em PL/pgSQL permite:
- Gerar mensagens explicando o que deu ruim.
- Parar a execução do código em caso de erro crítico.
- Logar problemas pra analisar depois.
Níveis principais de mensagens no PL/pgSQL
O PL/pgSQL suporta vários níveis de mensagens que ajudam a galera dev a diagnosticar e resolver problemas de boa. Olha só:
- NOTICE: mostra uma mensagem informativa. Usado pra debug.
- WARNING: avisa sobre um possível problema, mas não para o programa.
- EXCEPTION: erro crítico, para a execução do programa (e devolve o controle pra quem chamou).
Níveis de mensagens no PL/pgSQL
| Nível da mensagem | Descrição |
|---|---|
NOTICE |
Informação ou mensagem de debug. Não afeta a execução |
WARNING |
Aviso sobre possíveis problemas. Serve como dica |
EXCEPTION |
Erro sério que termina a execução do programa |
Sintaxe do comando RAISE
Pra gerar mensagens e tratar erros, usa-se o comando RAISE. A sintaxe básica é assim:
RAISE <nível da mensagem> 'texto da mensagem' [, variáveis...];
<nível da mensagem>—NOTICE,WARNING,EXCEPTION.'texto da mensagem'— descrição do problema.[variáveis...]— valores extras que você pode colocar na mensagem.
Exemplo 1: usando RAISE NOTICE
Às vezes é importante saber o que tá rolando dentro da sua função. Tipo, pra debugar um loop:
DO $$
BEGIN
FOR i IN 1..5 LOOP
RAISE NOTICE 'Valor atual de i: %', i;
END LOOP;
END
$$;
Resultado: Mostra no console as linhas Valor atual de i: 1, Valor atual de i: 2 e assim vai até 5.
Exemplo 2: usando RAISE EXCEPTION
Agora imagina que você tá escrevendo uma função que precisa terminar com erro em certas situações:
DO $$
BEGIN
IF 1 = 1 THEN
RAISE EXCEPTION 'Algo deu errado!';
END IF;
END
$$;
Resultado: a execução para e a mensagem de erro aparece no console.
Trabalhando com parâmetros no RAISE
Usando parâmetros, dá pra personalizar a mensagem. Pra isso, usa os placeholders %:
Exemplo 3: inserindo variáveis no RAISE
DO $$
DECLARE
student_name TEXT := 'Ivan';
average_score NUMERIC := NULL;
BEGIN
IF average_score IS NULL THEN
RAISE EXCEPTION 'O estudante % não tem média!', student_name;
END IF;
END
$$;
Resultado: mensagem O estudante Ivan não tem média!.
Como você vê, o % é trocado pela variável student_name, deixando a mensagem mais clara.
Gerando erros customizados
Erro não é só desastre! Às vezes você precisa criar erro de propósito pra proteger o código de dados errados.
Exemplo 4: checando valores de entrada
Vamos escrever uma função que checa se o número passado é negativo e lança erro se for:
CREATE OR REPLACE FUNCTION check_positive(value NUMERIC)
RETURNS TEXT AS $$
BEGIN
IF value < 0 THEN
RAISE EXCEPTION 'O número % é negativo!', value;
END IF;
RETURN 'Número ok.';
END;
$$ LANGUAGE plpgsql;
Agora vamos testar a função:
SELECT check_positive(-5);
Resultado: mensagem de erro O número -5 é negativo!.
Se passar um valor positivo:
SELECT check_positive(10);
Resultado: Número ok.
Tratando erros no contexto
Legal que você sabe gerar erros. Mas melhor ainda é tratar eles conforme a situação. Pra isso, usa o bloco BEGIN ... EXCEPTION.
Estrutura do tratamento de erros
BEGIN
-- Seu código principal
EXCEPTION
WHEN TIPO_DE_ERRO THEN
-- O que fazer se der esse erro
WHEN OUTRO_ERRO THEN
-- O que fazer pra outro erro
WHEN OTHERS THEN
-- Tratar todos os outros erros
END;
Vamos explicar os pedaços:
EXCEPTION— palavra-chave que marca o começo do bloco de tratamento de erros.WHEN— permite indicar o tipo específico de erro pra tratar, tipounique_violationoudivision_by_zero.OTHERS— serve pra tratar todos os erros que não foram especificados nosWHEN.
Exemplo 5: tratando divisão por zero
Vamos mostrar como tratar erro com um exemplo simples de função de divisão:
CREATE OR REPLACE FUNCTION safe_divide(a NUMERIC, b NUMERIC)
RETURNS NUMERIC AS $$
BEGIN
-- Tentando dividir
RETURN a / b;
EXCEPTION
WHEN division_by_zero THEN
RAISE WARNING 'Tentativa de dividir por zero. Retornando NULL.';
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
Testando a função:
SELECT safe_divide(10, 2); -- Resultado esperado: 5
SELECT safe_divide(10, 0); -- Resultado esperado: NULL e aviso no console
Erros comuns ao usar RAISE
Esquecer o nível da mensagem. Se você esquecer de colocar o nível, o PostgreSQL vai dar erro.
Errado:
RAISE 'Mensagem sem nível';
Certo:
RAISE NOTICE 'Mensagem com nível NOTICE';
Parâmetros errados. Se usar %, garante que passou o número certo de variáveis.
Errado:
RAISE NOTICE 'Exemplo com parâmetro %';
Certo:
RAISE NOTICE 'Exemplo com parâmetro %', 'valor';
Exagero. Usar RAISE EXCEPTION demais pode interromper operações importantes. Use com moderação.
Dicas úteis
- Cuidado com o bloco
WHEN OTHERS. Sempre que possível, especifique erros concretos pra não capturar erros que deveriam ser tratados de outro jeito. - Use
RAISEpra debugar. Nunca deixe erros sem tratamento. - Não esquece da performance. Tratar erro pode ser pesado, principalmente em procedimentos grandes.
Se você fizer tudo certinho, seus procedimentos vão ficar resistentes e aguentar até os bugs mais inesperados. O PM vai ficar orgulhoso de você!
GO TO FULL VERSION