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.
- A forma
INSERT INTO tabela (colunas) VALUES (valores);e o que cada parte faz. - Como o banco escolhe o
idda linha nova sozinho. - O que acontece com as colunas que você não citou:
NULLou 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,UNIQUEeFOREIGN KEY. - A diferença entre o editor do guia (que volta ao banco limpo) e o terminal (onde o
INSERTé para valer).
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ário | No 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 ordem | VALUES ('Lívia Rocha', 'livia.rocha@exemplo.com.br', 'Teresina') |
| Campos que você não preencheu | Ficam em branco (NULL) ou com o valor padrão |
| O número da ficha | O 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 umWHERE estado = 'PI'não acha a Lívia. Siga o padrão que a tabela já usa. - A coluna
vipnão estava na lista, e mesmo assim ficou0. 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:
| Coluna | Ficou | Por quê |
|---|---|---|
id | 31 | É a chave primária: o banco escolhe o próximo número. |
email, cidade, estado, nascimento | NULL | Não têm valor padrão: ficam em branco, "desconhecido" (aula O Valor NULL). |
vip | 0 | Foi 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 temDEFAULT 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.
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
| Forma | Quando usar | Cuidado |
|---|---|---|
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 fora | Quando o valor é desconhecido ou o padrão serve. | Colunas NOT NULL sem DEFAULT não podem ficar de fora. |
Escrever NULL no valor | Para 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.
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.
INSERT INTO categoria (nome)
VALUES ('Pet Shop');
A mensagem: no such table: categoria. A tabela se chama categorias, no plural.
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.
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.
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').
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'.
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;
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
| Escrita | O que faz |
|---|---|
INSERT INTO t (a, b) VALUES (1, 'x'); | Uma linha nova, com a = 1 e b = 'x' |
| Coluna fora da lista | Recebe o DEFAULT, ou NULL se não houver padrão |
id fora da lista | O 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 telefone | A coluna não existe nessa tabela |
no such table: categoria | A tabela não existe (confira o plural) |
1 values for 2 columns | Faltou valor (ou sobrou coluna) |
table categorias has 3 columns but 2 values were supplied | Sem a lista de colunas, faltou valor |
NOT NULL constraint failed: categorias.nome | Coluna obrigatória ficou em branco |
UNIQUE constraint failed: categorias.id | Esse id já existe |
FOREIGN KEY constraint failed | Aponta para uma linha que não existe em outra tabela |
no such column: Pet | Texto sem aspas |
near "Ávila": syntax error | Apóstrofo sem dobrar |
Exercícios
1. Complete o comando
2. O apóstrofo
Como se escreve, em SQL, o texto Pão D'Ouro?
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. Umidrepetido dáUNIQUE constraint failed. - Coluna fora da lista recebe o
DEFAULTouNULL; se forNOT NULLsem 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
INSERTgrava no arquivo, e as chaves estrangeiras só são conferidas depois dePRAGMA foreign_keys = ON;.