Bora mergulhar mais fundo no PL/pgSQL e começar a usar ele de verdade.
Bloco de código
O bloco de código no PL/pgSQL é tipo o tijolinho básico da linguagem. Dá pra dizer que é o esqueleto onde ficam nossas funções, procedures e toda aquela mágica. O bloco garante que a lógica roda, os dados são tratados, os erros são controlados, tudo num só "container".
Os blocos PL/pgSQL são organizados e têm três partes principais:
DECLARE: declaração de variáveis (opcional).BEGIN ... END: bloco principal de execução, onde a lógica acontece.EXCEPTION: tratamento de erros (opcional).
Pra quem curte analogia: imagina uma receita de comida. Mesmo que o texto da receita comece com a lista de ingredientes, a mágica mesmo rola no preparo. No PL/pgSQL:
DECLARE— é a lista de ingredientes (variáveis).BEGIN ... END— é onde mistura, frita e cozinha.EXCEPTION— é o plano B se queimar alguma coisa.
Sintaxe do bloco PL/pgSQL
Primeiro, bora ver a estrutura geral do bloco, tipo o "esqueleto". Depois a gente coloca carne (ou queijo vegano, se preferir) — a lógica de verdade.
DO $$
DECLARE
-- Aqui declaramos as variáveis
student_count INT;
BEGIN
-- Aqui vai a lógica
SELECT COUNT(*) INTO student_count FROM students;
RAISE NOTICE 'Total de estudantes: %', student_count;
EXCEPTION
-- Aqui tratamos os erros
WHEN OTHERS THEN
RAISE NOTICE 'Ocorreu um erro.';
END;
$$;
Bora destrinchar isso passo a passo.
DECLARE— aqui a gente declara as variáveis. O legal é que o PL/pgSQL aceita quase todos os tipos de dados do PostgreSQL — desde o humildeINTEGERaté o exótico JSONB. Pra declarar uma variável, é só dar um nome, tipo de dado e, se quiser, valor inicial.
Exemplo:
DECLARE
student_name TEXT; -- Variável pro nome do estudante
course_count INT := 0; -- Começa valendo 0
is_graduated BOOLEAN; -- Variável booleana
Repara que as variáveis podem ser inicializadas (tipo course_count) ou não.
BEGIN ... END— bloco principal de execução.
Essa parte do bloco é onde a mágica acontece. Aqui dá pra:
- Rodar queries SQL (
SELECT,INSERT, etc). - Mexer nos dados.
- Usar estruturas de controle (
IF,LOOP, etc). - Mostrar mensagens de debug com
RAISE.
Exemplo:
BEGIN
SELECT COUNT(*) INTO student_count FROM students;
IF student_count > 0 THEN
RAISE NOTICE 'Temos estudantes!';
ELSE
RAISE NOTICE 'Nenhum estudante encontrado.';
END IF;
END;
EXCEPTION— tratamento de erros (opcional).
Se rolar algum erro durante a execução do bloco, a seção EXCEPTION deixa a gente capturar e fazer algo útil — tipo mostrar uma mensagem ou rodar um código alternativo.
Exemplo:
BEGIN
SELECT COUNT(*) INTO student_count FROM non_existing_table; -- Erro!
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Opa, algo deu ruim!';
END;
Exemplo real: contando estudantes
Agora vamos juntar tudo num exemplo que pode ser útil de verdade. Vamos escrever um bloco PL/pgSQL que conta quantos estudantes tem na tabela students e mostra uma mensagem.
DO $$
DECLARE
total_students INT; -- Variável pra guardar o número de estudantes
BEGIN
-- Contando os estudantes
SELECT COUNT(*) INTO total_students FROM students;
-- Mostrando o resultado
RAISE NOTICE 'Número de estudantes: %', total_students;
EXCEPTION
-- Tratando possíveis erros, tipo se a tabela não existir
WHEN OTHERS THEN
RAISE NOTICE 'Ocorreu um erro ao contar estudantes.';
END;
$$;
Rodando esse bloco, vai aparecer uma mensagem no console. Tipo: Número de estudantes: 42.
Dicas sobre uso de variáveis
Bora ver uns pontos importantes:
Atribuindo valores às variáveis. Pra jogar dados numa variável, usa o operador SELECT INTO:
SELECT COUNT(*) INTO total_students FROM students;
Inicializando variáveis. Se você não der um valor pra variável na declaração, ela começa como NULL.
Exemplo:
DECLARE
my_var INT; -- Valor é NULL
Variáveis do tipo RECORD. Esse é um tipo coringa, dá pra guardar uma linha da tabela. Exemplo:
DECLARE
student RECORD;
BEGIN
SELECT * INTO student FROM students WHERE id = 1;
RAISE NOTICE 'Nome do estudante: %, Idade: %', student.name, student.age;
END;
Exemplo: contando cursos de um estudante
Agora vamos resolver um problema prático: contar quantos cursos um estudante tá matriculado e mostrar o resultado.
DO $$
DECLARE
student_id INT := 1; -- ID do estudante
course_count INT; -- Variável pro número de cursos
BEGIN
-- Contando os cursos
SELECT COUNT(*) INTO course_count
FROM enrollments
WHERE student_id = student_id;
-- Mostrando a mensagem
RAISE NOTICE 'Estudante ID % está matriculado em % cursos.', student_id, course_count;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Ocorreu um erro ao processar o estudante ID %', student_id;
END;
$$;
Esse bloco é flexível: dá pra mudar o student_id pra ver quantos cursos outros estudantes têm.
Erros e como evitar
Se o PL/pgSQL dentro de você já tá pulando igual salsicha no micro-ondas, relaxa. No começo é normal trombar com uns errinhos clássicos. Olha só:
Esquecer de declarar a variável. Se você esquecer de declarar a variável com DECLARE, o PL/pgSQL vai reclamar que a variável "não existe".
Tentar usar NULL como valor. Se a variável foi declarada mas não recebeu valor, ela vai ser NULL. Isso pode dar uns bugs estranhos. Exemplo:
IF my_var = NULL THEN -- NÃO funciona!
Use IS NULL:
IF my_var IS NULL THEN
Usar errado a seção EXCEPTION. Às vezes a galera captura todos os erros (WHEN OTHERS), mas não faz nada com eles. Isso pode esconder o problema real. Melhor mostrar a mensagem do erro:
RAISE NOTICE 'Erro: %', SQLERRM;
GO TO FULL VERSION