INSERT: inserindo dados em tabelas

Inserir dados em tabelas é uma das operações mais fundamentais em qualquer banco de dados relacional. O comando INSERT permite adicionar novas linhas a uma tabela, seja com valores literais, resultados de consultas ou combinações de ambos. Dominar suas variações é essencial para qualquer profissional que trabalhe com SQL.

1. Sintaxe Básica do INSERT

A estrutura fundamental do comando INSERT é:

INSERT INTO nome_tabela (coluna1, coluna2, coluna3)
VALUES (valor1, valor2, valor3);

Inserindo valores em todas as colunas (ordem implícita)

Quando você insere valores para todas as colunas da tabela, pode omitir a lista de colunas. Nesse caso, a ordem dos valores deve corresponder exatamente à ordem das colunas na definição da tabela.

-- Considerando a tabela: clientes(id, nome, email, data_cadastro)
INSERT INTO clientes
VALUES (1, 'Maria Silva', 'maria@email.com', '2024-01-15');

Especificando colunas explicitamente (ordem explícita e flexível)

Especificar as colunas é a prática recomendada, pois torna o código mais legível e resiliente a mudanças na estrutura da tabela. Você pode inserir valores em qualquer ordem:

INSERT INTO clientes (nome, email, data_cadastro, id)
VALUES ('João Santos', 'joao@email.com', '2024-01-20', 2);

Essa abordagem também permite inserir apenas em colunas específicas, deixando as demais com seus valores padrão.

2. Inserindo Múltiplas Linhas de Uma Vez

Inserir várias linhas em um único comando é mais eficiente do que executar múltiplos INSERTs individuais, pois reduz o número de viagens ao banco de dados e o overhead de transações.

INSERT INTO clientes (id, nome, email, data_cadastro)
VALUES 
    (3, 'Ana Oliveira', 'ana@email.com', '2024-02-01'),
    (4, 'Carlos Pereira', 'carlos@email.com', '2024-02-05'),
    (5, 'Lucia Costa', 'lucia@email.com', '2024-02-10');

Vantagens de desempenho

Inserções em lote são significativamente mais rápidas, especialmente ao inserir centenas ou milhares de registros. O banco de dados pode otimizar a operação como uma única transação implícita.

Limitações e boas práticas

Embora não haja um limite fixo universal, muitos bancos de dados impõem restrições de tamanho máximo para uma instrução SQL. Como boa prática:
- Para grandes volumes (acima de 10.000 linhas), divida em lotes menores
- Monitore o tempo de execução para evitar bloqueios prolongados
- Considere usar comandos de cópia em massa (COPY, BULK INSERT) para datasets muito grandes

3. Inserindo Dados com SELECT (INSERT...SELECT)

Uma das variações mais poderosas do INSERT é combiná-lo com uma consulta SELECT para copiar dados entre tabelas:

INSERT INTO clientes_vip (id, nome, email)
SELECT id, nome, email
FROM clientes
WHERE total_compras > 1000;

Filtrando dados durante a inserção

Você pode aplicar qualquer cláusula WHERE, JOIN ou subconsulta para selecionar exatamente os registros desejados:

INSERT INTO relatorio_mensal (cliente_id, total, mes)
SELECT c.id, SUM(p.valor), '2024-01'
FROM clientes c
JOIN pedidos p ON c.id = p.cliente_id
WHERE p.data BETWEEN '2024-01-01' AND '2024-01-31'
GROUP BY c.id;

Combinando colunas e funções

O SELECT de origem pode incluir funções, expressões e constantes:

INSERT INTO log_auditoria (tabela, acao, usuario, data_hora)
SELECT 'clientes', 'INSERCAO', CURRENT_USER, NOW()
FROM clientes
WHERE data_cadastro = CURRENT_DATE;

4. Lidando com Valores Padrão e NULL

Utilizando DEFAULT

Colunas com valores padrão definidos na criação da tabela podem ser preenchidas automaticamente usando a palavra-chave DEFAULT:

CREATE TABLE produtos (
    id SERIAL PRIMARY KEY,
    nome VARCHAR(100),
    preco DECIMAL(10,2) DEFAULT 0.00,
    ativo BOOLEAN DEFAULT true
);

INSERT INTO produtos (nome, preco, ativo)
VALUES ('Notebook', 2500.00, DEFAULT);

Inserindo NULL explicitamente

Para colunas que aceitam valores nulos, você pode inserir NULL explicitamente:

INSERT INTO clientes (id, nome, email, telefone)
VALUES (6, 'Pedro Alves', 'pedro@email.com', NULL);

Colunas com auto-incremento (SERIAL)

Colunas definidas como SERIAL (ou AUTO_INCREMENT) são gerenciadas automaticamente pelo banco de dados. Você pode omiti-las completamente no INSERT:

INSERT INTO categorias (nome, descricao)
VALUES ('Eletrônicos', 'Produtos eletrônicos em geral');
-- O campo id será preenchido automaticamente

5. Inserções com Conflito e Tratamento de Erros

Violações de chave primária ou unique são comuns ao inserir dados. O PostgreSQL oferece a cláusula ON CONFLICT para lidar com essas situações.

ON CONFLICT DO NOTHING

Ignora silenciosamente linhas que causariam conflito:

INSERT INTO clientes (id, nome, email)
VALUES (1, 'Maria Silva', 'maria@email.com')
ON CONFLICT (id) DO NOTHING;

ON CONFLICT DO UPDATE (UPSERT)

Atualiza registros existentes quando ocorre conflito, combinando INSERT e UPDATE em uma única operação:

INSERT INTO estoque (produto_id, quantidade)
VALUES (101, 50)
ON CONFLICT (produto_id) 
DO UPDATE SET quantidade = estoque.quantidade + EXCLUDED.quantidade;

A palavra-chave EXCLUDED refere-se aos valores que seriam inseridos, permitindo operações como acréscimos ou substituições parciais.

6. Boas Práticas e Cuidados ao Inserir

Validação de tipos de dados e formatação de strings

Sempre respeite os tipos definidos na tabela. Strings devem estar entre aspas simples, datas no formato ISO (YYYY-MM-DD) e números sem aspas:

INSERT INTO eventos (titulo, data_evento, capacidade)
VALUES ('Workshop SQL', '2024-03-15', 100);

Transações e atomicidade

Para garantir consistência em inserções que dependem umas das outras, use transações explícitas:

BEGIN;
INSERT INTO pedidos (cliente_id, data, total)
VALUES (10, CURRENT_DATE, 150.00);

INSERT INTO itens_pedido (pedido_id, produto_id, quantidade, preco)
VALUES (LASTVAL(), 205, 2, 75.00);
COMMIT;

Se algo der errado, você pode executar ROLLBACK para desfazer todas as alterações.

Impacto em índices e performance

Cada INSERT atualiza índices associados à tabela, o que pode impactar a performance em tabelas com muitos índices. Para inserções em massa:
- Considere desabilitar índices não essenciais temporariamente
- Use comandos especializados como COPY (PostgreSQL) ou BULK INSERT (SQL Server)
- Monitore o crescimento do log de transações

Inserir dados corretamente é a base para manter a integridade e a performance do banco de dados. Dominar o comando INSERT em suas diversas variações permite construir aplicações robustas e eficientes.

Referências