Em várias linguagens de programação, quase não tem diferença entre funções e procedimentos. No SQL tem sim. No PostgreSQL, funções e procedimentos não são só dois jeitos diferentes de rodar código. São paradigmas de pensamento diferentes.
Função em SQL não pode alterar dados no banco. Ela só pode trabalhar com os dados que recebe e devolver um resultado baseado neles. Ela existe pra ser usada dentro de queries SELECT.
Procedimento em SQL foi feito pra mexer no banco. Por isso, pode trabalhar com transações (diferente das funções), escrever coisas no banco. E não pode ser usada dentro de SELECT.
Aqui vai um resumo comparativo:
| Característica | Função (FUNCTION) | Procedimento (PROCEDURE) |
|---|---|---|
| Retorna dados | ✅ Sim (RETURNS ...) |
❌ Não (só executa ações) |
| Chamada via | SELECT, PERFORM |
CALL |
| Pode em queries | ✅ Sim | ❌ Não |
Pode estar em DO |
✅ Sim | ❌ Não |
Suporta COMMIT, ROLLBACK |
❌ Não | ✅ Sim |
| Entrou no PostgreSQL | Desde o começo | Desde a versão 11 |
Diferenças no SQL
No SQL normal, função parece uma expressão: ela calcula e retorna um valor. Procedimento é uma instrução: ele faz alguma coisa, mas não participa de expressões.
Função em SQL
SELECT calculate_discount(200);
- Pode ser usada em
WHERE,ORDER BY,INSERT,UPDATEe por aí vai. - Tem que ser pura: não pode mudar o estado do banco (se for IMMUTABLE/STABLE).
Procedimento em SQL
CALL process_order(123);
- Não retorna resultado.
- Pode fazer
COMMIT,ROLLBACK, chamarRAISE, rodar loops.
Diferenças no PL/pgSQL
Funções no PostgreSQL podem ser vistas como um grupo de cálculos. Elas são bem flexíveis: dá pra passar parâmetros, usar if, loops, cursores, subqueries, retornar linhas, escalares, tabelas.
Funções em PL/pgSQL
CREATE FUNCTION square(x INT) RETURNS INT AS $$
BEGIN
RETURN x * x;
END;
$$ LANGUAGE plpgsql;
Características:
RETURNSé obrigatório- Pode usar
DECLARE,BEGIN,END,LOOP,IF,CASE - Não pode fazer
COMMIT/ROLLBACK - Pode ser chamada em
SELECT,UPDATE,CHECK,WHERE,RETURNING
Chamada:
SELECT square(5); -- vai retornar 25
Procedimentos em PL/pgSQL
Procedimentos são um jeito de controlar ações. Eles são perfeitos quando você precisa:
- fazer várias etapas com lógica;
- atualizar e inserir grandes volumes de dados;
- usar controle de transações:
COMMIT,ROLLBACK,SAVEPOINT.
CREATE PROCEDURE log_event(msg TEXT) AS $$
BEGIN
INSERT INTO logs(message) VALUES (msg);
COMMIT;
END;
$$ LANGUAGE plpgsql;
Características:
- Não tem
RETURNS - Só pode ser chamada via
CALL - Pode usar
COMMIT,ROLLBACK,SAVEPOINT - Boa pra processamento em lote, migrações, ETL
Chamada:
CALL log_event('Processamento finalizado');
Por que funções e procedimentos são separados
Porque eles têm objetivos diferentes no SQL:
| Funções | Procedimentos |
|---|---|
| "Calcular algo e retornar" | "Fazer algo e não retornar resultado" |
| Chamada do SQL | Chamada como comando |
| Não podem controlar transações | Podem controlar transações |
Usadas em SELECT, JOIN, WHERE |
Usadas em CALL, scripts |
Principal vantagem do procedimento — COMMIT
Procedimentos podem controlar transações dentro deles. Ou seja, dentro do procedimento você pode fazer:
BEGIN;
-- lógica
SAVEPOINT point1;
-- tentativa de atualização
ROLLBACK TO point1;
COMMIT;
Já em função, COMMIT e ROLLBACK são proibidos. Se tentar, vai receber: ERROR: invalid transaction termination in function
Isso significa que função tem que ser determinística e segura, enquanto procedimento pode ser "trabalho sujo" — limpar, logar, inserir.
Tabela comparativa
| Característica | FUNCTION |
PROCEDURE |
|---|---|---|
| Retorna valor | ✅ RETURNS |
❌ |
Usada em SELECT |
✅ | ❌ |
| Chamada | SELECT, PERFORM, DO |
Só CALL |
| Pode ser usada em trigger | ✅ | ❌ (só funções) |
Transações dentro (COMMIT) |
❌ Proibido | ✅ Permitido |
| Uso de parâmetros OUT | Pelo RETURNS TABLE, RECORD |
Pelos parâmetros OUT direto |
| Boa pra cálculos | ✅ | 🚫 não é pra isso |
| Boa pra ETL, carga | 🚫 limitado | ✅ perfeito |
| Pode usar cursores | ✅ Sim | ✅ Sim |
Quando usar o quê?
Use função se:
- quer um valor de retorno;
- vai chamar em
SELECT, filtrar dados; - é um cálculo simples, checagem ou wrapper pra SQL.
Use procedimento se:
- quer executar ações complexas;
- precisa de controle de transações;
- vai processar lotes, migrar dados, arquivar, logar.
GO TO FULL VERSION