SQL INSERT INTO

Até aqui você só leu dados com o SELECT. Mas a Loja Aurora não para: chegam clientes novos, produtos novos, até uma seção nova na loja. Para guardar uma linha nova numa tabela, o SQL tem o comando INSERT INTO ("inserir em"). Nesta aula você vai cadastrar uma categoria, um cliente e um produto, vai ver o banco escolher o número (o id) sozinho e vai conhecer as mensagens que o SQLite dá quando o cadastro está errado: coluna que não existe, campo obrigatório vazio, número repetido.

Você vai aprender
  • A forma INSERT INTO tabela (colunas) VALUES (valores); e o que cada parte faz.
  • Como o banco escolhe o id da linha nova sozinho.
  • O que acontece com as colunas que você não citou: NULL ou o valor padrão.
  • Por que é melhor sempre escrever a lista de colunas.
  • Como escrever texto com apóstrofo, como D'Ávila.
  • Os erros reais: coluna ou tabela que não existe, número de valores errado, NOT NULL, UNIQUE e FOREIGN KEY.
  • A diferença entre o editor do guia (que volta ao banco limpo) e o terminal (onde o INSERT é para valer).
Pode inserir sem medo

No editor do guia, cada Rodar começa do banco limpo: a Loja Aurora é carregada de novo e só então o seu SQL roda. O que você inserir aparece no resultado e some no próximo Rodar. Por isso, nos exemplos desta aula, o INSERT vem seguido de um SELECT na mesma caixa: é o jeito de ver a linha nova antes que ela desapareça.


A ideia: uma ficha nova no fichário

Pense no fichário de clientes da loja. Cadastrar um cliente é pegar uma ficha em branco, preencher os campos (nome, email, cidade…) e guardá-la no fichário. O INSERT faz o mesmo:

No fichárioNo SQL
Escolher o fichário (clientes, produtos…)INSERT INTO clientes
Dizer quais campos você vai preencher(nome, email, cidade)
Escrever o conteúdo de cada campo, na mesma ordemVALUES ('Lívia Rocha', 'livia.rocha@exemplo.com.br', 'Teresina')
Campos que você não preencheuFicam em branco (NULL) ou com o valor padrão
O número da fichaO banco escolhe o próximo id

1. O primeiro INSERT

A Aurora vai abrir uma seção de produtos para animais. A tabela categorias tem 8 linhas; vamos acrescentar a 9ª:

INSERT INTO categorias (nome, descricao)
VALUES ('Pet Shop', 'Ração, brinquedos e acessórios para animais');

SELECT * FROM categorias;
INSERT INTO
"Inserir em": vai entrar uma linha nova.
categorias
A tabela que recebe a linha.
(nome, descricao)
A lista de colunas que você vai preencher, entre parênteses e separadas por vírgula.
VALUES
"Valores": daqui em diante vem o conteúdo.
('Pet Shop', 'Ração, …')
A lista de valores, na mesma ordem das colunas: o 1º valor vai para a 1ª coluna (nome), o 2º para a 2ª (descricao). Texto vai entre aspas simples. A vírgula dentro das aspas é só uma letra do texto; as vírgulas que separam valores ficam fora das aspas.
;
Fim do comando. Depois dele vem outro comando, o SELECT, para você ver o resultado.

O quadro mostra duas coisas, na ordem em que os comandos rodaram: primeiro "1 linha afetada" (o INSERT guardou uma linha), depois a tabela inteira, com a Pet Shop no fim, com o id 9.

Quem escolheu o 9?

Você não escreveu o id. Na Aurora, ele é uma INTEGER PRIMARY KEY: a chave primária, o "número da ficha" que identifica cada linha (aula PRIMARY KEY). Quando você não diz o número, o SQLite usa o maior id que já existe, mais 1. O maior era 8, então a Pet Shop ganhou o 9. Deixar o banco escolher é o jeito normal de trabalhar: ninguém precisa descobrir qual é o próximo número livre.

Experimente: a Aurora também vai vender artigos para carro. Acrescente, antes do SELECT, um INSERT com a categoria de nome Automotivo e descrição Acessórios para o carro. Rode e veja o id que ela recebeu.

SELECT * FROM categorias;
INSERT INTO categorias (nome, descricao)
VALUES ('Automotivo', 'Acessórios para o carro');

SELECT * FROM categorias;

2. Um cliente novo

A Lívia Rocha, de Teresina, fez a primeira compra. A tabela clientes tem 7 colunas: id, nome, email, cidade, estado, nascimento e vip. A Ana preenche cinco:

INSERT INTO clientes (nome, email, cidade, estado, nascimento)
VALUES ('Lívia Rocha', 'livia.rocha@exemplo.com.br', 'Teresina', 'PI', '2002-04-15');

SELECT * FROM clientes WHERE id >= 30;

A Lívia virou a cliente 31 (a última era a 30, Rosângela Dias). Repare em três detalhes:

  • A data de nascimento entrou como texto no formato ISO, '2002-04-15', igual às outras datas da Aurora (veja por que na aula BETWEEN).
  • O estado é a sigla 'PI', igual aos outros clientes. O banco não confere isso: se você escrever 'Piauí', ele guarda 'Piauí', e depois um WHERE estado = 'PI' não acha a Lívia. Siga o padrão que a tabela já usa.
  • A coluna vip não estava na lista, e mesmo assim ficou 0. Isso é a próxima seção.

3. As colunas que ficam de fora

O Joaquim Leite comprou no balcão e só disse o nome. A Ana cadastra só o que sabe:

INSERT INTO clientes (nome)
VALUES ('Joaquim Leite');

SELECT * FROM clientes WHERE id = 31;

Cada coluna que ficou de fora da lista recebeu um de dois valores:

ColunaFicouPor quê
id31É a chave primária: o banco escolhe o próximo número.
email, cidade, estado, nascimentoNULLNão têm valor padrão: ficam em branco, "desconhecido" (aula O Valor NULL).
vip0Foi criada com DEFAULT 0: quando ninguém diz nada, vale 0 (aula DEFAULT).

Como saber quais colunas têm valor padrão e quais são obrigatórias? No terminal, o comando de ponto .schema clientes mostra como a tabela foi criada (aula Comandos de Ponto). Na Aurora, ele mostra nome TEXT NOT NULL e vip INTEGER NOT NULL DEFAULT 0: o nome é obrigatório; o vip, se faltar, vira 0.

Deixar em branco de propósito

Você também pode citar a coluna e escrever NULL como valor, para deixar claro que o branco foi intencional. Sem aspas: NULL é o valor desconhecido, e 'NULL' seria a palavra.

INSERT INTO clientes (nome, email, cidade, estado)
VALUES ('Joaquim Leite', NULL, 'Picos', 'PI');

SELECT * FROM clientes WHERE id = 31;

4. Sem a lista de colunas

O SQL também aceita o INSERT sem a lista de colunas. Aí você precisa dar um valor para todas as colunas, na ordem em que a tabela foi criada (para categorias: id, nome, descricao):

INSERT INTO categorias
VALUES (9, 'Pet Shop', 'Ração, brinquedos e acessórios para animais');

SELECT * FROM categorias WHERE id > 7;

Funcionou, mas tem três problemas: você precisa decorar a ordem das colunas, precisa escolher o id na mão, e se um dia alguém acrescentar uma coluna na tabela (aula ALTER TABLE), esse INSERT passa a dar erro. Esqueça um valor e veja:

INSERT INTO categorias
VALUES ('Pet Shop', 'Ração, brinquedos e acessórios para animais');

"A tabela categorias tem 3 colunas, mas foram fornecidos 2 valores." Boa prática: escreva sempre a lista de colunas. O INSERT fica mais longo, mas qualquer pessoa entende o que vai para onde, e ele continua funcionando quando a tabela muda.


5. Escolhendo o id (e o erro do número repetido)

Se você quiser, pode dizer o id, como qualquer outra coluna:

INSERT INTO categorias (id, nome)
VALUES (20, 'Pet Shop');

INSERT INTO categorias (nome)
VALUES ('Automotivo');

SELECT * FROM categorias WHERE id > 7;

A Pet Shop ficou com o 20, como pedido. E a Automotivo, sem id, ganhou o 21: "o maior que existe, mais 1". Os números de 9 a 19 ficaram sem uso, e não tem problema nenhum nisso: o id só precisa ser único, não precisa ser seguido. Mas único ele precisa ser:

INSERT INTO categorias (id, nome)
VALUES (8, 'Pet Shop');

A mensagem: UNIQUE constraint failed: categorias.id ("a restrição de unicidade falhou: categorias.id"). Já existe a categoria 8 (Jardim), e uma chave primária não pode se repetir. O INSERT inteiro é recusado; a Jardim continua lá, intacta. Por isso o normal é não escrever o id: o banco nunca escolhe um número repetido.


6. Texto com apóstrofo

Um fornecedor novo se chama Empório D'Ávila. O apóstrofo é o mesmo caractere da aspa simples, que fecha o texto. Para pôr um apóstrofo dentro do texto, escreva duas aspas simples seguidas:

INSERT INTO fornecedores (nome, cidade, estado, pais)
VALUES ('Empório D''Ávila', 'Picos', 'PI', 'Brasil');

SELECT id, nome, cidade FROM fornecedores;

No banco ficou um apóstrofo só: Empório D'Ávila, ao lado da Loja D'Água, que já existia. As duas aspas são só o jeito de escrever. Com uma aspa só, o SQLite acha que o texto acabou em 'Empório D' e não entende o resto (você vai ver o erro em Quando dá errado).


7. Um produto novo (e as chaves estrangeiras)

A tabela produtos tem duas colunas que apontam para outras tabelas: categoria_id (o número de uma categoria) e fornecedor_id (o número de um fornecedor). São chaves estrangeiras (aula FOREIGN KEY). Um produto novo de jardinagem (categoria 8), do fornecedor 1:

INSERT INTO produtos (nome, categoria_id, fornecedor_id, preco, estoque)
VALUES ('Mangueira de Jardim 15m', 8, 1, 64.9, 25);

SELECT * FROM produtos WHERE categoria_id = 8;
64.9
O preço, com ponto e sem aspas: é um número. Com vírgula (64,9), o SQLite entenderia dois valores.
25
O estoque inicial, também sem aspas.
descontinuado
Ficou de fora e virou 0: também tem DEFAULT 0.

E se a categoria não existir? O editor do guia liga a verificação das chaves estrangeiras, e o SQLite recusa:

INSERT INTO produtos (nome, categoria_id, fornecedor_id, preco)
VALUES ('Ração para Gatos 1kg', 99, 1, 25.9);

A mensagem: FOREIGN KEY constraint failed ("a restrição de chave estrangeira falhou"). Não existe categoria 99; o banco não deixa um produto apontar para o nada. A mensagem não diz qual coluna é a culpada: confira cada número que aponta para outra tabela.


8. No terminal, o INSERT é para valer

No editor, tudo volta ao normal no próximo Rodar. No terminal, não: o INSERT grava a linha no arquivo loja.db. A Ana insere a Pet Shop, sai do sqlite3, entra de novo, e ela continua lá:

$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> INSERT INTO categorias (nome, descricao) VALUES ('Pet Shop', 'Ração, brinquedos e acessórios para animais');
sqlite> SELECT * FROM categorias WHERE id > 7;
8|Jardim|Ferramentas e artigos de jardinagem
9|Pet Shop|Ração, brinquedos e acessórios para animais
sqlite> .quit
$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> SELECT * FROM categorias WHERE id > 7;
8|Jardim|Ferramentas e artigos de jardinagem
9|Pet Shop|Ração, brinquedos e acessórios para animais    « gravada no arquivo
sqlite> .quit

Repare que o INSERT não mostrou nada no terminal: quando dá certo, o sqlite3 fica quieto. Os erros, esses ele mostra, com uma "moldura" a mais que no editor:

$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> INSERT INTO categorias (nome) VALUES ('Automotivo', 'Peças');
Parse error: 2 values for 1 columns
sqlite> INSERT INTO categorias (id, nome) VALUES (1, 'Pet Shop');
Runtime error: UNIQUE constraint failed: categorias.id (19)
sqlite> .quit

Parse error quer dizer que o SQLite nem conseguiu entender o comando; Runtime error, que entendeu, mas deu errado ao executar. O (19) é o número interno desse tipo de erro (restrição violada). O miolo da mensagem é o mesmo do editor.

No terminal, as chaves estrangeiras começam desligadas

O editor do guia liga a verificação das chaves estrangeiras. O programa sqlite3, não: cada vez que você abre o banco, ela começa desligada, e um produto com uma categoria que não existe entra sem reclamar. Veja no lab da Ana:

$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> INSERT INTO produtos (nome, categoria_id, fornecedor_id, preco) VALUES ('Ração 1kg', 99, 1, 25.9);
sqlite> PRAGMA foreign_keys;
0                         « 0 = desligada: o INSERT acima passou
sqlite> PRAGMA foreign_keys = ON;
sqlite> INSERT INTO produtos (nome, categoria_id, fornecedor_id, preco) VALUES ('Ração 2kg', 99, 1, 45.9);
Runtime error: FOREIGN KEY constraint failed (19)
sqlite> .quit

A "Ração 1kg" ficou gravada apontando para uma categoria que não existe. Ao trabalhar no terminal, comece com PRAGMA foreign_keys = ON;. A aula FOREIGN KEY explica tudo isso com calma.


Formas diferentes de inserir

FormaQuando usarCuidado
INSERT INTO t (a, b) VALUES (1, 2);Sempre. É a forma recomendada.Mesmo número de colunas e de valores, na mesma ordem.
INSERT INTO t VALUES (…);Testes rápidos numa tabela que você conhece de cor.Precisa de todas as colunas, na ordem da tabela; quebra quando a tabela muda.
Deixar a coluna de foraQuando o valor é desconhecido ou o padrão serve.Colunas NOT NULL sem DEFAULT não podem ficar de fora.
Escrever NULL no valorPara mostrar que o branco é de propósito.Sem aspas.
Várias linhas num comando sóCadastrar muitos de uma vez.É a próxima aula: Inserindo Várias Linhas.
INSERT INTO … SELECT …Copiar linhas de uma consulta.Aula INSERT INTO SELECT.

Quando dá errado

Em todos estes casos, o SQLite recusa o INSERT inteiro: nenhuma linha entra pela metade.

Coluna que não existe
INSERT INTO clientes (nome, telefone)
VALUES ('Lívia Rocha', '(86) 99999-0000');

A mensagem: table clientes has no column named telefone ("a tabela clientes não tem coluna chamada telefone"). Na Aurora, quem tem telefone são os fornecedores, não os clientes. O mesmo acontece com um acento a mais: descrição em vez de descricao dá table categorias has no column named descrição.

Como consertar: confira os nomes das colunas com .schema clientes no terminal ou com um SELECT * FROM clientes no editor.

Tabela com o nome errado
INSERT INTO categoria (nome)
VALUES ('Pet Shop');

A mensagem: no such table: categoria. A tabela se chama categorias, no plural.

Quantidade de valores diferente da de colunas
INSERT INTO categorias (nome, descricao)
VALUES ('Pet Shop');

A mensagem: 1 values for 2 columns ("1 valor para 2 colunas"). Você prometeu duas colunas e entregou um valor. O contrário, (nome) VALUES ('Pet Shop', 'Para animais'), dá 2 values for 1 columns. Um caso clássico: um preço escrito com vírgula, 25,90, conta como dois valores (25 e 90).

Como consertar: uma coluna para cada valor, e decimal com ponto.

Campo obrigatório vazio
INSERT INTO categorias (descricao)
VALUES ('Ração, brinquedos e acessórios para animais');

A mensagem: NOT NULL constraint failed: categorias.nome. A coluna nome foi criada NOT NULL: não pode ficar em branco, e ficou, porque não estava na lista (aula NOT NULL). Na Aurora, os nomes de tudo são obrigatórios, e também o preço dos produtos e a data dos pedidos.

Como consertar: inclua a coluna obrigatória e um valor para ela.

Texto sem aspas, ou com aspas duplas
INSERT INTO categorias (nome)
VALUES (Pet);

A mensagem: no such column: Pet. Sem aspas, Pet parece o nome de uma coluna. Com duas palavras, VALUES (Pet Shop), a mensagem muda para near "Shop": syntax error. E com aspas duplas, VALUES ("Pet Shop"), o SQLite responde no such column: "Pet Shop" - should this be a string literal in single-quotes?: aspas duplas são para nomes de coluna; texto vai entre aspas simples.

Como consertar: VALUES ('Pet Shop').

Apóstrofo sem dobrar
INSERT INTO fornecedores (nome, pais)
VALUES ('Empório D'Ávila', 'Brasil');

A mensagem: near "Ávila": syntax error. O texto terminou em 'Empório D', e o SQLite tropeçou no Ávila solto que veio depois.

Como consertar: dobre o apóstrofo: 'Empório D''Ávila'.

Esqueceu uma palavra (ou o ponto e vírgula)
INSERT INTO categorias (nome)
VALUE ('Pet Shop');

A mensagem: near "VALUE": syntax error. É VALUES, no plural. (O MySQL aceita VALUE como sinônimo, por isso você pode encontrá-lo em exemplos da internet; o SQLite não aceita.)Do mesmo jeito, INSERT categorias … sem o INTO dá near "categorias": syntax error. E dois INSERT seguidos sem o ; entre eles dão near "INSERT": syntax error, apontando para o começo do segundo.

Missão: este INSERT está com dois erros e não cadastra ninguém. Rode, leia a mensagem, conserte, rode de novo, até a cliente Lívia Rocha entrar.

INSERT INTO clientes (nome, email, cidade)
VALUES ("Lívia Rocha", 'livia.rocha@exemplo.com.br');

SELECT * FROM clientes WHERE id >= 30;
INSERT INTO clientes (nome, email, cidade)
VALUES ('Lívia Rocha', 'livia.rocha@exemplo.com.br', 'Teresina');

SELECT * FROM clientes WHERE id >= 30;
Nos outros bancos

O INSERT INTO tabela (colunas) VALUES (valores) é do SQL padrão e funciona igual no MySQL, no PostgreSQL e no SQL Server. O que muda é o id automático: no SQLite, basta a coluna ser INTEGER PRIMARY KEY; nos outros, a coluna precisa ser criada de um jeito especial (AUTO_INCREMENT no MySQL, GENERATED … AS IDENTITY ou SERIAL no PostgreSQL, IDENTITY no SQL Server). Isso fica para a aula AUTOINCREMENT. As mensagens de erro também mudam de texto em cada banco, mas os motivos são os mesmos: coluna que não existe, obrigatório vazio, chave repetida.


Referência rápida

EscritaO que faz
INSERT INTO t (a, b) VALUES (1, 'x');Uma linha nova, com a = 1 e b = 'x'
Coluna fora da listaRecebe o DEFAULT, ou NULL se não houver padrão
id fora da listaO SQLite usa o maior id + 1
VALUES (…, NULL, …)Branco de propósito
'D''Ávila'Apóstrofo dentro do texto
INSERT INTO t VALUES (…);Sem lista: todas as colunas, na ordem da tabela
Mensagem do SQLite (editor)Quer dizer
table clientes has no column named telefoneA coluna não existe nessa tabela
no such table: categoriaA tabela não existe (confira o plural)
1 values for 2 columnsFaltou valor (ou sobrou coluna)
table categorias has 3 columns but 2 values were suppliedSem a lista de colunas, faltou valor
NOT NULL constraint failed: categorias.nomeColuna obrigatória ficou em branco
UNIQUE constraint failed: categorias.idEsse id já existe
FOREIGN KEY constraint failedAponta para uma linha que não existe em outra tabela
no such column: PetTexto sem aspas
near "Ávila": syntax errorApóstrofo sem dobrar

Exercícios

1. Complete o comando

categorias (nome) ('Pet Shop');

2. O apóstrofo

Como se escreve, em SQL, o texto Pão D'Ouro?

VALUES ()

3. A tabela clientes tem a coluna vip INTEGER NOT NULL DEFAULT 0. O que ela vale depois de INSERT INTO clientes (nome) VALUES ('Joaquim Leite');?

4. A maior categoria é a 8. Que id ganha INSERT INTO categorias (nome) VALUES ('Pet Shop');?

5. INSERT INTO produtos (nome, categoria_id, fornecedor_id, preco) VALUES ('Vaso', 8, 1, 25,90); dá qual erro?

Missão final: um produto novo no jardim

Missão: cadastre o produto Mangueira de Jardim 15m, da categoria 8 (Jardim), do fornecedor 1, com preço 64,90 e 25 unidades em estoque. Deixe o SELECT no fim, para ver o produto novo na lista.

SELECT id, nome, preco, estoque
FROM produtos
WHERE categoria_id = 8;
INSERT INTO produtos (nome, categoria_id, fornecedor_id, preco, estoque)
VALUES ('Mangueira de Jardim 15m', 8, 1, 64.9, 25);

SELECT id, nome, preco, estoque
FROM produtos
WHERE categoria_id = 8;

Rode de novo e repare: a mangueira sumiu e voltou, sempre com o id 46. Cada Rodar parte do banco limpo, com 45 produtos.


Resumo

  • INSERT INTO tabela (colunas) VALUES (valores); guarda uma linha nova. Os valores vão na mesma ordem das colunas.
  • Texto entre aspas simples; números sem aspas, com ponto decimal; apóstrofo dobrado ('D''Ávila').
  • Sem o id, o SQLite usa o maior que existe + 1. Um id repetido dá UNIQUE constraint failed.
  • Coluna fora da lista recebe o DEFAULT ou NULL; se for NOT NULL sem padrão, dá NOT NULL constraint failed.
  • Escreva sempre a lista de colunas: o comando fica claro e não quebra quando a tabela muda.
  • No editor, cada Rodar parte do banco limpo; no terminal, o INSERT grava no arquivo, e as chaves estrangeiras só são conferidas depois de PRAGMA foreign_keys = ON;.