Funções e procedimentos permitem armazenar lógica de negócio diretamente no banco de dados, onde ela pode ser invocada por qualquer aplicação conectada — independente de linguagem ou plataforma.
Característica
Função (FUNCTION)
Procedimento (PROCEDURE)
Retorna valor
Sim (escalar ou tabela)
Não (ou via parâmetros OUT)
Pode ser usada em SELECT
Sim
Não
Chamada com
Expressão SQL
CALL nome(...)
Controle de transação
Não (herda da transação chamante)
Sim (pode COMMIT/ROLLBACK)
Funções SQL Simples
A forma mais direta: o corpo é uma única expressão SQL.
CREATEORREPLACEFUNCTION total_alunos_curso(p_id_curso INT)RETURNS BIGINT AS $$SELECTCOUNT(*) FROM aluno WHERE id_curso = p_id_curso;$$ LANGUAGE sql;
-- Usando a função em uma consultaSELECT nome_curso, total_alunos_curso(id_curso) AS total_alunosFROM cursoORDERBY total_alunos DESC;
3 records
nome_curso
total_alunos
Engenharia de Software
6
Ciências Econômicas
6
Pedagogia
6
Funções SQL são ideais quando o corpo cabe em uma única instrução. Para lógica mais complexa, usa-se PL/pgSQL.
Funções PL/pgSQL
PL/pgSQL é a linguagem procedural nativa do PostgreSQL. Suporta variáveis, condicionais, laços e tratamento de exceções.
-- Classificar notas dos alunos de ENSSELECT a.nome, d.nome_disciplina, md.nota, classificar_nota(md.nota) AS conceitoFROM matricula_disciplina mdJOIN aluno a USING (id_aluno)JOIN disciplina d USING (id_disciplina)WHERE d.id_curso =311ORDERBY a.nome, d.semestre;
Displaying records 1 - 10
nome
nome_disciplina
nota
conceito
Diego Correia
Projeto Aplicado 2 - site WEB
6.8
MM — Médio
Diego Correia
Bases da Eng. de Software 2
6.1
MM — Médio
Isabela Freitas
Bases da Eng. de Software 2
4.3
MI — Médio Inferior
Isabela Freitas
Projeto Aplicado 2 - site WEB
7.2
MS — Médio Superior
Isabela Freitas
Bases da Eng. de Software 4
7.7
MS — Médio Superior
Isabela Freitas
Projeto Aplicado 4 - blockchain
0.4
II — Inferior
Juliana Nunes
Projeto Aplicado 2 - site WEB
6.1
MM — Médio
Juliana Nunes
Bases da Eng. de Software 2
1.9
II — Inferior
Larissa Araújo
Projeto Aplicado 2 - site WEB
6.3
MM — Médio
Larissa Araújo
Bases da Eng. de Software 2
6.1
MM — Médio
Estruturas de Controle
PL/pgSQL suporta as estruturas usuais de linguagens procedurais:
-- IF / ELSIF / ELSEIF condicao THEN...ELSIF outra_condicao THEN...ELSE...ENDIF;-- WHILEWHILE condicao LOOP...ENDLOOP;-- FOR sobre resultado de consultaFOR registro INSELECT... FROM... LOOP-- registro.colunaENDLOOP;
Exemplo: Função com Laço FOR
CREATEORREPLACEFUNCTION media_escola(p_id_escola INT)RETURNS NUMERICAS $$DECLARE v_total NUMERIC:=0; v_count INT:=0; v_salario NUMERIC;BEGINFOR v_salario INSELECT salario FROM professor WHERE id_escola = p_id_escolaLOOP v_total := v_total + v_salario; v_count := v_count +1;ENDLOOP;IF v_count =0THENRETURNNULL; ENDIF;RETURNROUND(v_total / v_count, 2);END;$$ LANGUAGE plpgsql;
-- Média salarial calculada via função vs. AVG nativoSELECT e.sigla, media_escola(e.id_escola) AS media_fn,ROUND(AVG(p.salario), 2) AS media_avgFROM escola eJOIN professor p ON p.id_escola = e.id_escolaGROUPBY e.id_escola, e.siglaORDERBY e.sigla;
3 records
sigla
media_fn
media_avg
EEMA
4800.00
4800.00
ESETI
4366.67
4366.67
ESG
6550.00
6550.00
Funções que Retornam Tabelas
O padrão SQL (e o PostgreSQL) permite que funções retornem um conjunto de linhas — chamadas de table functions.
-- Professores da ESETI (escola 31) via table functionSELECT*FROM professores_da_escola(31);
3 records
nome
ch_semanal
salario
Helena Carvalho
40
6700
Gustavo Costa
20
3300
Igor Melo
20
3100
A função pode ser usada diretamente na cláusula FROM, como uma tabela.
Procedimentos Armazenados
PROCEDURE difere de FUNCTION por não retornar um valor e por poder controlar transações internamente.
CREATEORREPLACEPROCEDURE reajustar_salarios(p_id_escola INT, p_percentual NUMERIC)LANGUAGE plpgsql AS $$BEGINUPDATE professorSET salario =ROUND(salario * (1+ p_percentual /100), 2)WHERE id_escola = p_id_escola; RAISE NOTICE 'Reajuste de % %% aplicado a % professor(es) da escola %', p_percentual, (SELECTCOUNT(*) FROM professor WHERE id_escola = p_id_escola), p_id_escola;END;$$;
-- Salários antes do reajusteSELECT nome, salario FROM professor WHERE id_escola =11ORDERBY nome;
2 records
nome
salario
Bruno Teixeira
6500
Carla Pinto
6600
-- Chamar o procedimento (5% de reajuste para ESG)CALL reajustar_salarios(11, 5);
-- Salários após o reajusteSELECT nome, salario FROM professor WHERE id_escola =11ORDERBY nome;
2 records
nome
salario
Bruno Teixeira
6825
Carla Pinto
6930
-- Desfazer o reajuste para não alterar os dados base do livroCALL reajustar_salarios(11, -100.0*5/105);
Listando Funções Criadas
-- Funções e procedimentos definidos no schema publicSELECT routine_name AS nome, routine_type AS tipo, data_type AS retornoFROM information_schema.routinesWHERE routine_schema ='public'ORDERBY routine_type, routine_name;
5 records
nome
tipo
retorno
classificar_nota
FUNCTION
text
media_escola
FUNCTION
numeric
professores_da_escola
FUNCTION
record
total_alunos_curso
FUNCTION
bigint
reajustar_salarios
PROCEDURE
NA
Para Praticar
-- Chamar classificar_nota para ver a distribuição de conceitos em ENSSELECT classificar_nota(nota) AS conceito,COUNT(*) AS quantidadeFROM matricula_disciplinaJOIN disciplina USING (id_disciplina)WHERE id_curso =311AND nota ISNOTNULLGROUPBY conceitoORDERBY quantidade DESC;
5 records
conceito
quantidade
MS — Médio Superior
7
MM — Médio
6
II — Inferior
3
MI — Médio Inferior
2
SS — Superior
2
-- Total de alunos por escola usando a função + JOINSELECT e.sigla,SUM(total_alunos_curso(c.id_curso)) AS total_alunosFROM escola eJOIN curso c ON c.id_escola = e.id_escolaGROUPBY e.id_escola, e.siglaORDERBY total_alunos DESC;