No desenvolvimento de aplicações modernas, é comum delegar toda a lógica para o backend (Python, Java, Node). No entanto, quando falamos de escala, performance e segurança, o banco de dados (PostgreSQL) pode (e deve) ser seu maior aliado.
Neste artigo, que complementa o vídeo do canal @luis.alexandre, vamos explorar por que encapsular inserções em Functions no PostgreSQL é uma prática de arquitetura superior.
1. Os Problemas do SQL “Hardcoded” na Aplicação
Quando sua aplicação dispara um
INSERT INTO tabela...
diretamente, você enfrenta três desafios:
-
Round-trips desnecessários: Cada validação ou consulta extra gera uma viagem de ida e volta na rede entre o servidor da app e o banco.
-
Exposição do Esquema: Sua aplicação precisa conhecer o nome exato das tabelas e colunas, aumentando o acoplamento.
-
Tráfego de Rede: Você envia comandos SQL longos em vez de apenas uma chamada simples.
2. A Vantagem das Functions (Stored Procedures)
Ao utilizar uma Function, você move a inteligência para onde o dado reside:
-
Menos Tráfego: Você envia apenas
SELECT nome_funcao(parâmetros) -
Performance: O PostgreSQL pré-compila o plano de execução da função.
-
Segurança: Você pode dar permissão de execução (EXECUTE) na função para o usuário da app, sem dar permissão de escrita direta na tabela.
3. O Código Exemplo
Abaixo, apresento a função que discutimos no vídeo. Ela valida os dados antes de efetivar a inserção.
CREATE TABLE produto(
codigo integer primary key,
nome varchar(120) not null,
preco decimal not null
);
INSERT INTO produto (codigo, nome, preco) VALUES (1, 'Prdoduto A', 12.55);
COMMIT;
SELECT * FROM produto;
DROP FUNCTION IF EXISTS inserir_produto(integer, varchar, numeric);
CREATE FUNCTION inserir_produto(
p_codigo integer,
p_nome varchar,
p_preco numeric
)
RETURNS integer
LANGUAGE plpgsql
AS $$
DECLARE
v_count integer;
v_sqlstate text;
BEGIN
-- Código válido (>0 e dentro do INTEGER)
IF p_codigo <= 0 OR p_codigo > 2147483647 THEN
RETURN 2;
END IF;
-- Verificar se código já existe (estilo Oracle)
SELECT COUNT(*)
INTO v_count
FROM produto
WHERE codigo = p_codigo;
IF v_count > 0 THEN
RETURN 1;
END IF;
-- Nome nulo
IF p_nome IS NULL THEN
RETURN 3;
END IF;
-- Tamanho do nome
IF length(p_nome) < 3 OR length(p_nome) > 120 THEN
RETURN 4;
END IF;
-- Nome duplicado
SELECT COUNT(*)
INTO v_count
FROM produto
WHERE nome = p_nome;
IF v_count > 0 THEN
RETURN 5;
END IF;
-- Preço válido
IF p_preco <= 0 OR p_preco >= 10000 THEN
RETURN 6;
END IF;
-- Insert
INSERT INTO produto (codigo, nome, preco)
VALUES (p_codigo, p_nome, p_preco);
RETURN 0;
EXCEPTION
WHEN OTHERS THEN
-- Captura o SQLSTATE real do PostgreSQL
GET STACKED DIAGNOSTICS v_sqlstate = RETURNED_SQLSTATE;
-- Retorna o código do PostgreSQL como NÚMERO
RETURN v_sqlstate::integer;
END;
$$;
Como testar:
Para executar a função e ver a validação em ação, use o comando:
SELECT inserir_produto(23, 'Caneta Azulx', 2.50);
Possíveis resultados:
Código Significado
0 Inserção realizada com sucesso
1 Código já existe
2 Código fora do intervalo permitido
3 Nome nulo
4 Nome com tamanho inválido
5 Nome de produto duplicado
6 Preço inválido
outro SQLSTATE do erro do PostgreSQL
4. Conclusão
Usar Functions não é “coisa de banco de dados antigo”, é uma decisão de Engenharia de Software. Você garante que, independente de qual linguagem acesse seu banco (seja um script Python ou um sistema em Java), a regra de negócio será aplicada de forma consistente e rápida.
Gostou dessa dica? Assista ao vídeo completo no meu canal do YouTube para ver a explicação detalhada dos slides!
Links Úteis:
-
-
Canal YouTube: @luis.alexandre
-
Documentação PostgreSQL: PL/pgSQL
-
-
- PDF Slides – PDF
- Vídeo Youtube para criar PostgreSQL – Supabase:
- Vídeo Youtube para demostrando a criação e teste da Function:
