INSERT adiciona linhas a uma tabela
O INSERT é o comando que você usa para colocar novas linhas em uma tabela. A sintaxe é curta e previsível:
Três detalhes que valem atenção:
INSERT INTO books— a tabela de destino.(title, author, year)— as colunas para as quais você está fornecendo valores.VALUES (...)— os valores, na mesma ordem da lista de colunas.
Repare que id não aparece na lista de colunas, então o SQLite preenche automaticamente (é uma INTEGER PRIMARY KEY, que recebe o rowid). Qualquer coluna que você deixar de fora assume o valor padrão (default) ou NULL, caso não exista um.
Sempre liste as colunas no INSERT
Dá para omitir a lista de colunas e passar valores para todas elas, na ordem em que foram declaradas:
-- Funciona, mas é frágil:
INSERT INTO books VALUES (NULL, 'Dune', 'Frank Herbert', 1965);
Não faça isso. Basta alguém adicionar uma coluna em books para que toda instrução desse tipo quebre ou passe a inserir valores na coluna errada. Liste as colunas explicitamente:
Listar as colunas explicitamente funciona como uma forma de documentação — a instrução fica legível por conta própria, sem que você precise abrir a definição da tabela para entender o que cada valor representa.
Inserir várias linhas no SQLite
Dá para inserir várias linhas em um único comando, basta listar mais tuplas de valores:
Isso fica bem mais limpo do que três INSERT separados, e o SQLite trata tudo como um único comando. Mas o ganho real de performance em cargas grandes vem de envolver os inserts numa transação — já chego lá.
Bulk insert no SQLite: use uma transação
Por padrão, cada INSERT roda na sua própria transação. O SQLite faz um fsync ao final de cada uma, e é exatamente isso que deixa aquele loop ingênuo lento — não são os inserts em si.
Agrupe tudo:
Um fsync em vez de cinco. Quando se trata de milhares de linhas, a diferença pode chegar a duas ou três ordens de grandeza. Se qualquer coisa falhar no meio do caminho, o ROLLBACK desfaz o lote inteiro.
Esse padrão é a receita para bulk insert no SQLite. Use sempre que precisar — não importa se está chamando o SQLite a partir de Python, Node ou Rust: envolva seu loop com BEGIN / COMMIT.
INSERT ... SELECT: copiando dados de outra tabela
Dá para popular uma tabela a partir de uma consulta, em vez de usar valores literais:
As colunas do SELECT são casadas por posição com a lista de colunas do INSERT. Os nomes não precisam bater — a ordem precisa. Esse é o jeito padrão de arquivar registros, montar tabelas de relatório ou copiar um subconjunto de dados durante uma migração.
DEFAULT VALUES e colunas omitidas
Se uma coluna tem cláusula DEFAULT, dá pra deixá-la fora da lista de colunas que o SQLite preenche o valor padrão sozinho:
created_at recebe o timestamp atual porque não fornecemos nenhum valor. Se você quer criar uma linha usando só os valores padrão — útil para linhas de marcação (placeholder) —, use a forma DEFAULT VALUES:
Duas novas linhas, ambas com value = 0 e ids gerados automaticamente.
INSERT OR IGNORE: ignorando duplicatas
Quando uma linha viola uma constraint UNIQUE ou PRIMARY KEY, o comportamento padrão do SQLite é abortar o comando e devolver um erro:
Erro: UNIQUE constraint failed: users.email
INSERT OR IGNORE troca isso por "ignora a linha problemática sem reclamar":
Sobram três linhas. A duplicata é descartada sem disparar erro. Essa é a forma idiomática no SQLite de expressar "inserir se não existir" para dados de seed simples — sem precisar de um SELECT antes para checar, nem de tratamento de exceção.
INSERT OR REPLACE: sobrescrevendo duplicatas
O INSERT OR REPLACE apaga a linha conflitante e insere a nova no lugar:
Vale ficar de olho num detalhe: o REPLACE é DELETE + INSERT, não UPDATE. Se a linha apagada tinha chaves estrangeiras apontando para ela com ON DELETE CASCADE, os filhos vão junto. E qualquer coluna que você não citar no novo INSERT volta para o valor padrão — ela não preserva o valor antigo.
Para a maioria dos casos do tipo "atualiza se existir, insere se não existir", o que você quer mesmo é um upsert de verdade com ON CONFLICT ... DO UPDATE. Isso tem página própria.
Recapitulando rapidinho
INSERT INTO tabela (colunas) VALUES (...)— a forma básica. Sempre liste as colunas.- Para inserir várias linhas no SQLite, use tuplas separadas por vírgula depois do
VALUES. - Em cargas grandes (bulk insert no SQLite), envolva os inserts num
BEGIN/COMMIT. INSERT INTO ... SELECT ...copia linhas a partir de uma consulta.DEFAULT VALUEScria uma linha só com os valores padrão; colunas omitidas também caem no default.INSERT OR IGNOREno SQLite pula as linhas em conflito;INSERT OR REPLACEsobrescreve (via delete + insert).
A seguir: UPDATE
Inserir dados é metade da história. A outra metade é alterar linhas que já existem — incrementar um contador, corrigir um erro de digitação, marcar um pedido como enviado. Para isso existe o UPDATE, que tem suas próprias manhas (em especial o WHERE, que merece atenção redobrada). É o que vem na sequência.
Perguntas frequentes
Como inserir uma linha no SQLite?
Use INSERT INTO tabela (col1, col2) VALUES (val1, val2);. Listar as colunas é opcional, mas recomendo fortemente — assim o comando continua funcionando mesmo se a tabela ganhar uma coluna nova depois. Sem a lista de colunas, você é obrigado a passar um valor para cada coluna, na ordem em que foram declaradas.
Como inserir várias linhas de uma vez no SQLite?
Coloque várias tuplas entre parênteses depois do VALUES, separadas por vírgula: INSERT INTO t (a, b) VALUES (1, 2), (3, 4), (5, 6);. Para cargas grandes de verdade (milhares de linhas), envolva os inserts numa única transação com BEGIN e COMMIT — é daí que vem o ganho real de performance, não da sintaxe de múltiplas linhas em si.
O que faz o INSERT OR IGNORE no SQLite?
O INSERT OR IGNORE simplesmente pula as linhas que violariam uma restrição UNIQUE, PRIMARY KEY ou NOT NULL, em vez de disparar erro. A linha conflitante é descartada silenciosamente e o resto do comando segue normalmente. Útil quando você quer um comportamento do tipo "insere se ainda não existe" sem precisar fazer um SELECT antes pra checar.
Por que aparece 'UNIQUE constraint failed' no INSERT?
O SQLite encontrou uma linha existente com o mesmo valor numa coluna UNIQUE ou PRIMARY KEY. Ou o valor é duplicado mesmo, ou você está rodando um script de seed novamente. Troque para INSERT OR IGNORE para ignorar duplicatas, INSERT OR REPLACE para sobrescrever, ou use ON CONFLICT ... DO UPDATE (upsert) quando precisar de mais controle.