SQL Erros Comuns
Todo mundo erra SQL, todo dia: uma letra trocada no nome da tabela, uma vírgula sobrando, aspas do tipo errado. O SQLite sempre avisa, mas avisa em inglês e com poucas palavras. Esta página é um dicionário dessas mensagens: cada uma aparece exatamente como sai no editor do guia e no terminal do sqlite3, com a tradução, a causa mais comum, o conserto e a aula onde o assunto é explicado.
- Deu erro? Copie o começo da mensagem (por exemplo,
no such column) e procure nesta página com Ctrl+F. - As mensagens foram colhidas no SQLite 3.50.4: no editor do guia e no terminal da Ana (
ana@notebook), com o banco da Loja Aurora. Nenhuma foi escrita de memória. - Os quadros "Resultado" desta página rodam o SQL errado de verdade no seu navegador: a mensagem em vermelho é a que o seu SQLite deu agora.
Como ler uma mensagem de erro
O mesmo erro aparece um pouco diferente em cada lugar. No editor do guia, a mensagem sai crua, do jeito que o SQLite a escreveu:
SELECT nomee FROM clientes;
No terminal do SQLite, o programa sqlite3 acrescenta um prefixo e, muitas vezes, uma seta mostrando onde ele se perdeu:
$ sqlite3 loja.db
SQLite version 3.50.4 2025-07-30 19:33:53
Enter ".help" for usage hints.
sqlite> SELECT nomee FROM clientes;
Parse error: no such column: nomee
SELECT nomee FROM clientes;
^--- error here
- Parse error:
- "Erro de análise". O SQLite nem começou a rodar: o problema foi achado ao ler o comando (nome que não existe, sintaxe errada). Nada no banco mudou.
- no such column: nomee
- A mensagem em si: "não existe a coluna
nomee". É o mesmo texto que o editor mostra. - SELECT nomee FROM clientes;
- O terminal repete o seu comando…
- ^--- error here
- …e aponta o lugar do erro ("o erro está aqui"). Quando o ponto fica no fim da linha, a seta vira
error here ---^, com o^à direita.
Os prefixos que você vai encontrar no terminal:
| Prefixo | Onde aparece | Quer dizer |
|---|---|---|
Parse error: | no prompt sqlite> | O comando nem rodou: erro de nome ou de escrita. |
Runtime error: … (19) | no prompt sqlite> | O comando começou a rodar e parou no meio (uma regra da tabela foi quebrada, por exemplo). O número no fim é o código do erro (tabela Os códigos numéricos). |
Error: in prepare, … | com o SQL na linha de comando: sqlite3 loja.db "SELECT …" | O mesmo que Parse error: falhou ao preparar (ler) o comando. |
Error: stepping, … (8) | com o SQL na linha de comando | O mesmo que Runtime error: falhou ao executar. |
Error: unknown command … | no prompt sqlite>, depois de um ponto | Comando de ponto que não existe (veja No terminal). |
Quando um comando dá erro, ele inteiro é cancelado: um INSERT de várias linhas que falha na terceira não grava nem a primeira. No editor, a execução também para no comando com erro; os comandos de baixo não rodam.
1. Nomes que não existem
O grupo mais comum de todos: o SQLite não achou a tabela, a coluna ou a função com o nome que você escreveu. Quase sempre é uma letra trocada, um plural esquecido ou um apelido mal usado. Os nomes das tabelas do guia estão todos no plural: clientes, produtos, pedidos, itens_pedido…
| Mensagem (como sai) | Em português | Causa comum | Como resolver | Aula |
|---|---|---|---|---|
no such table: cliente | não existe a tabela cliente | Nome da tabela digitado errado (aqui, faltou o "s"); ou o banco aberto não é o que você pensa. | Confira o nome com .tables no terminal ou na aula do banco. No terminal, confira se abriu o arquivo certo (veja nada.db). | SELECT |
no such column: nomee | não existe a coluna nomee | Nome da coluna digitado errado, ou a coluna é de outra tabela. | Confira as colunas com .schema clientes no terminal ou com SELECT * FROM clientes LIMIT 1;. | Escolhendo Colunas |
no such column: clientes.id | não existe a coluna clientes.id | Você deu um apelido à tabela (FROM clientes c) e depois usou o nome original. Depois do apelido, a tabela só atende pelo apelido. | Use o apelido: c.id. | Apelidos (AS) |
ambiguous column name: id | nome de coluna ambíguo: id | Num JOIN, duas tabelas têm uma coluna com esse nome (clientes.id e pedidos.id) e o SQLite não sabe qual você quer. | Diga de qual tabela: clientes.id ou c.id. | INNER JOIN |
no such function: abc | não existe a função abc | Nome errado, ou uma função de outro banco (como NOW() do MySQL ou LEN() do SQL Server). | Veja o nome no SQLite nas páginas de referência: Texto, Numéricas, Data. | Funções de Texto |
wrong number of arguments to function substr() | número errado de argumentos para a função substr() | Faltou (ou sobrou) algum valor dentro dos parênteses. | Confira quantos argumentos a função recebe na referência. | Funções de Texto |
table clientes already exists | a tabela clientes já existe | CREATE TABLE com um nome que já está no banco. | Escolha outro nome, ou use CREATE TABLE IF NOT EXISTS (cria só se não existir). | CREATE TABLE |
no such table: nada (no DROP TABLE) | não existe a tabela nada | Apagar uma tabela que não existe. | DROP TABLE IF EXISTS nada; não dá erro. | DROP TABLE |
duplicate column name: email | nome de coluna repetido: email | ALTER TABLE … ADD COLUMN de uma coluna que já existe, ou duas colunas com o mesmo nome no CREATE TABLE. | Use outro nome, ou confira com .schema se a coluna já está lá. | ALTER TABLE |
cannot drop PRIMARY KEY column: "id" | não dá para apagar a coluna de chave primária "id" | ALTER TABLE … DROP COLUMN na chave primária. | O SQLite não deixa. Para mudar a chave, crie uma tabela nova e copie os dados. | ALTER TABLE |
Veja o caso do apelido rodando de verdade:
SELECT c.nome FROM clientes c WHERE clientes.id = 1;
E o do nome ambíguo, que só aparece quando há duas tabelas:
SELECT id, nome FROM clientes JOIN pedidos ON pedidos.cliente_id = clientes.id;
No terminal da Ana, a seta mostra exatamente qual id está ambíguo: o primeiro, depois do SELECT.
sqlite> SELECT id, nome FROM clientes JOIN pedidos ON pedidos.cliente_id = clientes.id;
Parse error: ambiguous column name: id
SELECT id, nome FROM clientes JOIN pedidos ON pedidos.cliente_id = clientes.id
^--- error here
2. Erros de escrita (sintaxe)
Aqui o SQLite não conseguiu nem entender a frase. A mensagem típica é near "X": syntax error, "perto de X: erro de sintaxe". O X é a palavra onde ele percebeu o erro, que nem sempre é onde o erro está: muitas vezes o problema é a palavra logo antes.
| Mensagem (como sai) | Em português | Causa comum | Como resolver | Aula |
|---|---|---|---|---|
near "SELEC": syntax error | perto de "SELEC": erro de sintaxe | Palavra-chave digitada errado. | Corrija a palavra: SELECT. | SELECT |
near "FROM": syntax error | perto de "FROM": erro de sintaxe | Vírgula sobrando antes do FROM: SELECT nome, FROM clientes. | Apague a vírgula depois da última coluna. | Escolhendo Colunas |
near ";": syntax error | perto de ";": erro de sintaxe | O comando acabou antes da hora: WHERE, LIMIT ou OFFSET sem nada depois, ou um parêntese aberto sem fechar. | Complete a parte que ficou vazia ou feche o parêntese. | WHERE |
near "WHERE": syntax error | perto de "WHERE": erro de sintaxe | Partes fora de ordem, como um WHERE depois do ORDER BY. | A ordem é sempre SELECT … FROM … WHERE … GROUP BY … HAVING … ORDER BY … LIMIT. | ORDER BY |
near "DESC": syntax error | perto de "DESC": erro de sintaxe | Palavra repetida: ORDER BY nome DESC DESC. | Apague a repetição. | ORDER BY |
near ".": syntax error | perto de ".": erro de sintaxe | Um comando de ponto (.tables, .schema) digitado no editor do guia. Eles são do programa sqlite3, não são SQL. | Use comandos de ponto só no terminal. No editor, as tabelas se veem com SELECT name FROM sqlite_schema;. | Comandos de Ponto |
unrecognized token: "'Ana" | pedaço não reconhecido: "'Ana" | Aspa simples aberta e não fechada: WHERE nome = 'Ana. | Feche a aspa: 'Ana'. Para escrever uma aspa dentro do texto, dobre-a: 'Loja D''Água'. | WHERE |
incomplete input | entrada incompleta | O SQL terminou no meio, sem fechar um parêntese ou uma aspa e sem ;. | Feche o que ficou aberto. No terminal, isso aparece de outro jeito (veja abaixo). | O Terminal do SQLite |
no such column: "Ana Carvalho Lima" - should this be a string literal in single-quotes? | não existe a coluna "Ana Carvalho Lima"; isto não deveria ser um texto entre aspas simples? | Texto entre aspas duplas. Em SQL, aspas duplas são para nomes (de tabela e coluna); texto vai entre aspas simples. | Troque por aspas simples: 'Ana Carvalho Lima'. | WHERE |
Este é o erro de quem vem do Excel ou de outra linguagem de programação, onde texto vai entre aspas duplas:
SELECT nome, email FROM clientes WHERE nome = "Ana Carvalho Lima";
O SQLite leu "Ana Carvalho Lima" como o nome de uma coluna e não achou coluna nenhuma com esse nome. A própria mensagem dá a dica: should this be a string literal in single-quotes?, "isto não deveria ser um texto entre aspas simples?". Essa é a mensagem do editor do guia. No terminal, o sqlite3 do Debian não reclama:
sqlite> SELECT nome FROM clientes WHERE nome = "Ana Carvalho Lima"; Ana Carvalho Lima sqlite>
Atenção: o editor do guia usa um SQLite configurado como o padrão do SQL manda (a opção DQS=0). O sqlite3 que vem no Debian (e em muitas outras distribuições) é "tolerante": quando não acha a coluna, aceita o texto entre aspas duplas sem reclamar. Não conte com isso: além de fora do padrão, se um dia existir uma coluna com aquele nome, a consulta passa a comparar com a coluna, sem erro nenhum (a aula WHERE mostra isso acontecendo). Use sempre aspas simples para texto.
O comando que não termina, no terminal
No editor, um parêntese aberto sem ; dá incomplete input. No prompt do sqlite3, ninguém reclama: o terminal acha que você ainda vai continuar o comando e muda o prompt para ...> (continuação). Se houver um parêntese aberto, o prompt mostra quantos: (x1...>.
sqlite> SELECT nome FROM clientes WHERE (id = 1
(x1...> ;
Parse error: near ";": syntax error
SELECT nome FROM clientes WHERE (id = 1 ;
error here ---^
Quando o ; finalmente chega, o SQLite vê o parêntese que não fechou e reclama. Se o terminal "travou" mostrando ...>, quase sempre falta um ; (ou uma aspa, ou um parêntese): digite o que falta e Enter. Já com o SQL na linha de comando, a mensagem é a mesma do editor:
$ sqlite3 loja.db "SELECT nome FROM clientes WHERE (id = 1"
Error: in prepare, incomplete input
$ sqlite3 loja.db "SELECT nome FROM clientes WHERE nome = 'Ana"
Error: in prepare, unrecognized token: "'Ana"
SELECT nome FROM clientes WHERE nome = 'Ana
error here ---^
Missão: esta consulta tem dois erros. Rode, leia a mensagem, conserte, rode de novo e leia a próxima mensagem. No fim, ela deve mostrar o nome e o email da cliente Ana Carvalho Lima.
SELECT nome, email FROM cliente WHERE nome = "Ana Carvalho Lima";
SELECT nome, email FROM clientes WHERE nome = 'Ana Carvalho Lima';
3. Regras da tabela quebradas (constraint failed)
Estes erros aparecem quando o comando está bem escrito, mas os dados quebram uma regra que a tabela tem. Constraint quer dizer "restrição", e failed, "falhou": a regra não foi cumprida, e o comando inteiro foi recusado. No terminal, eles vêm como Runtime error com o código (19).
| Mensagem (como sai) | Em português | Causa comum | Como resolver | Aula |
|---|---|---|---|---|
UNIQUE constraint failed: clientes.id | restrição UNIQUE falhou: clientes.id | Inserir um valor que já existe numa coluna que não aceita repetição (a chave primária ou uma coluna UNIQUE). | Não informe o id (o SQLite escolhe um livre), ou use um valor que não exista. Para "inserir ou atualizar", veja INSERT … ON CONFLICT. | UNIQUE, PRIMARY KEY |
NOT NULL constraint failed: categorias.nome | restrição NOT NULL falhou: categorias.nome | Coluna obrigatória ficou vazia: o valor foi NULL ou a coluna ficou de fora do INSERT e não tem DEFAULT. | Informe um valor para a coluna. | NOT NULL |
FOREIGN KEY constraint failed | restrição de chave estrangeira falhou | Apontar para algo que não existe (um pedido do cliente 999) ou apagar algo que ainda é apontado (um cliente que tem pedidos). | Confira se o id apontado existe. A mensagem não diz qual coluna: confira uma por uma. | FOREIGN KEY |
CHECK constraint failed: preco > 0 | restrição CHECK falhou: preco > 0 | O valor não passou no teste da regra CHECK. A mensagem mostra a própria regra… | Use um valor que passe no teste. | CHECK |
CHECK constraint failed: preco_positivo | restrição CHECK falhou: preco_positivo | …ou o nome dela, se a regra foi criada com CONSTRAINT preco_positivo CHECK (…). | Dê nomes claros às regras: a mensagem fica mais fácil de entender. | CHECK |
datatype mismatch | tipo de dado incompatível | Um texto onde o SQLite exige um número inteiro: na chave INTEGER PRIMARY KEY (id = 'abc') ou em LIMIT 'x'. | Use um número inteiro. | Os Tipos no SQLite |
cannot store TEXT value in INTEGER column t.n | não dá para guardar um valor TEXT na coluna INTEGER t.n | Tabela STRICT (rígida) recebendo um valor do tipo errado. | Converta o valor ou corrija o dado. | Os Tipos no SQLite |
Dois exemplos rodando de verdade. A categoria 1 (Papelaria) já existe:
INSERT INTO categorias (id, nome, descricao) VALUES (1, 'Pet Shop', 'Ração e brinquedos para bichos');
E não existe cliente 999 para receber um pedido:
INSERT INTO pedidos (cliente_id, funcionario_id, data, frete) VALUES (999, 2, '2026-10-18', 0);
No terminal, os mesmos erros saem com o prefixo Runtime error e o código (19) no fim:
sqlite> INSERT INTO clientes (id, nome) VALUES (1, 'Teste');
Runtime error: UNIQUE constraint failed: clientes.id (19)
sqlite> INSERT INTO categorias (nome) VALUES (NULL);
Runtime error: NOT NULL constraint failed: categorias.nome (19)
sqlite> PRAGMA foreign_keys = ON;
sqlite> INSERT INTO pedidos (cliente_id, funcionario_id, data, frete) VALUES (999, 2, '2026-10-18', 0);
Runtime error: FOREIGN KEY constraint failed (19)
sqlite> INSERT INTO clientes (id, nome) VALUES ('abc', 'Teste');
Runtime error: datatype mismatch (20)
Repare no PRAGMA foreign_keys = ON; antes do pedido do cliente 999. No programa sqlite3, a checagem de chave estrangeira vem desligada e precisa ser ligada a cada vez que você abre o banco:
sqlite> PRAGMA foreign_keys; 0
Com 0 (desligada), aquele INSERT do cliente 999 passa sem erro nenhum, e o banco fica com um pedido de um cliente que não existe. No editor do guia, a Loja Aurora já é carregada com a checagem ligada. Mais em FOREIGN KEY e em PRAGMAs.
Missão: a Ana quer criar a categoria "Pet Shop", mas o INSERT dá UNIQUE constraint failed. Conserte para que a categoria nova entre (a tabela deve ficar com 9 categorias). Dica: quem precisa escolher o id?
INSERT INTO categorias (id, nome, descricao) VALUES (1, 'Pet Shop', 'Ração e brinquedos para bichos');
INSERT INTO categorias (nome, descricao)
VALUES ('Pet Shop', 'Ração e brinquedos para bichos');
4. Agregar e agrupar
As funções agregadas (COUNT, SUM, AVG…) e as funções de janela só podem aparecer em certos lugares da consulta. Usá-las no lugar errado dá um destes erros.
| Mensagem (como sai) | Em português | Causa comum | Como resolver | Aula |
|---|---|---|---|---|
misuse of aggregate function SUM() | uso errado da função agregada SUM() | Função agregada no WHERE. O WHERE olha uma linha por vez; a soma só existe depois de juntar as linhas. | Filtre grupos com HAVING, depois do GROUP BY. | HAVING |
aggregate functions are not allowed in the GROUP BY clause | funções agregadas não são permitidas no GROUP BY | GROUP BY COUNT(*): agrupar pelo resultado de uma conta que depende do próprio agrupamento. | Agrupe por uma coluna (GROUP BY cidade). | GROUP BY |
HAVING clause on a non-aggregate query | cláusula HAVING numa consulta sem agregação | HAVING sem GROUP BY e sem função agregada. | Para filtrar linhas, use WHERE. | HAVING |
DISTINCT aggregates must have exactly one argument | agregadas com DISTINCT precisam de exatamente um argumento | group_concat(DISTINCT nome, ', '): com DISTINCT, não dá para passar o separador. | Tire o DISTINCT ou o segundo argumento (o separador volta a ser a vírgula). | Funções Agregadas |
wrong number of arguments to function count() | número errado de argumentos para count() | COUNT(DISTINCT nome, cidade): o SQLite conta uma coluna só. | Conte as combinações numa subconsulta: SELECT COUNT(*) FROM (SELECT DISTINCT nome, cidade FROM clientes); | COUNT() |
misuse of window function ROW_NUMBER() | uso errado da função de janela ROW_NUMBER() | Função de janela sem OVER (…), ou usada no WHERE. | Escreva o OVER. Para filtrar pelo número, calcule numa subconsulta ou CTE e filtre por fora. | ROW_NUMBER |
SELECT nome FROM clientes WHERE SUM(id) > 10;
5. Contas de colunas que não fecham
Erros em que dois lados precisam ter a mesma quantidade de coisas e não têm: as colunas de um UNION, os valores de um INSERT, as colunas de uma subconsulta.
| Mensagem (como sai) | Em português | Causa comum | Como resolver | Aula |
|---|---|---|---|---|
SELECTs to the left and right of UNION do not have the same number of result columns | os SELECTs à esquerda e à direita do UNION não têm o mesmo número de colunas | Um lado com 2 colunas, o outro com 1. | Deixe os dois lados com as mesmas colunas, na mesma ordem. Se faltar uma, complete com NULL. | UNION |
table categorias has 3 columns but 2 values were supplied | a tabela categorias tem 3 colunas, mas foram dados 2 valores | INSERT INTO categorias VALUES (…) sem a lista de colunas e com valores de menos. | Escreva a lista de colunas: INSERT INTO categorias (nome) VALUES (…). | INSERT INTO |
2 values for 3 columns | 2 valores para 3 colunas | A lista de colunas tem 3 nomes e o VALUES, 2 valores. | Um valor para cada coluna da lista. | INSERT INTO |
sub-select returns 2 columns - expected 1 | a subconsulta devolve 2 colunas; era esperada 1 | WHERE id IN (SELECT id, nome …): o IN compara com uma coluna só. | Deixe só a coluna que interessa na subconsulta. | Subconsultas |
1st ORDER BY term out of range - should be between 1 and 1 | o 1º termo do ORDER BY está fora do intervalo: deveria estar entre 1 e 1 | ORDER BY 9 numa consulta de 1 coluna: o número quer dizer "a 9ª coluna do resultado". | Use um número de coluna que exista, ou, melhor, o nome da coluna. | ORDER BY |
1st GROUP BY term out of range - should be between 1 and 1 | o mesmo, no GROUP BY | GROUP BY 9 com 1 coluna. | Agrupe pelo nome da coluna. | GROUP BY |
SELECT nome, cidade FROM clientes UNION SELECT nome FROM fornecedores;
6. Transações
| Mensagem (como sai) | Em português | Causa comum | Como resolver | Aula |
|---|---|---|---|---|
cannot start a transaction within a transaction | não dá para começar uma transação dentro de outra | Dois BEGIN seguidos. | Termine a primeira com COMMIT ou ROLLBACK. Para "transação dentro de transação", use SAVEPOINT. | ROLLBACK e Savepoints |
cannot commit - no transaction is active | não dá para confirmar: nenhuma transação está aberta | COMMIT sem BEGIN antes (ou a transação já tinha terminado). | Nada a fazer: cada comando solto já foi gravado sozinho. | Transações |
cannot rollback - no transaction is active | não dá para desfazer: nenhuma transação está aberta | ROLLBACK sem BEGIN antes. | Sem transação, não há o que desfazer. Use BEGIN antes de mudar dados. | Transações |
7. No terminal: arquivo, trava e permissão
Estes só aparecem no programa sqlite3, com um banco de verdade num arquivo. O editor do guia usa um banco na memória, só seu, e nunca dá esses erros.
| Mensagem (como sai) | Em português | Causa comum | Como resolver | Aula |
|---|---|---|---|---|
database is locked (5) | o banco está trancado | Outro programa (ou outra janela do sqlite3) está no meio de uma transação de escrita no mesmo arquivo. | Termine a transação do outro lado (COMMIT ou ROLLBACK) e tente de novo. No sqlite3, .timeout 5000 faz esperar até 5 segundos antes de desistir. | Transações |
attempt to write a readonly database (8) | tentativa de escrever num banco somente leitura | O banco foi aberto com -readonly, ou o arquivo (ou a pasta dele) não tem permissão de escrita. | Abra sem -readonly, ou dê permissão de escrita ao arquivo (chmod u+w). | O Terminal do SQLite |
no such table: clientes (num banco "vazio") | não existe a tabela clientes | O nome do arquivo foi digitado errado. O sqlite3 não reclama de arquivo inexistente: ele cria um banco novo, vazio, com aquele nome. | Confira o nome do arquivo (ls) e apague o banco vazio criado por engano. | O Terminal do SQLite |
Error: unknown command or invalid arguments: "tabels". Enter ".help" for help | comando desconhecido ou argumentos inválidos: "tabels". Digite .help para ajuda | Comando de ponto digitado errado. | Veja a lista com .help ou na referência dos comandos de ponto. | Comandos de Ponto |
near "tables": syntax error | perto de "tables": erro de sintaxe | Esqueceu o ponto: tables virou uma tentativa de SQL. | Comandos de ponto começam com . e não levam ;. | Comandos de Ponto |
A Ana reproduziu cada um. Primeiro, o banco trancado: um sqlite3 rodando em segundo plano (o & no fim) abre uma transação exclusiva e a segura por 3 segundos; enquanto isso, outro tenta mudar o estoque:
$ (echo 'BEGIN EXCLUSIVE;'; sleep 3; echo 'COMMIT;') | sqlite3 loja.db & [1] 11 $ sleep 1 $ sqlite3 loja.db "UPDATE produtos SET estoque = estoque + 1 WHERE id = 1;" Error: in prepare, database is locked (5)
Depois, o banco somente leitura, das duas formas: com a opção -readonly e com o arquivo sem permissão de escrita (chmod 444):
$ sqlite3 -readonly loja.db "DELETE FROM clientes WHERE id = 30;" Error: stepping, attempt to write a readonly database (8) $ cp loja.db copia.db $ chmod 444 copia.db $ sqlite3 copia.db "DELETE FROM clientes WHERE id = 30;" Error: stepping, attempt to write a readonly database (8)
E o arquivo com nome errado, que vira um banco novo e vazio:
$ sqlite3 nada.db "SELECT * FROM clientes;" Error: in prepare, no such table: clientes $ ls nada.db nada.db « o sqlite3 criou o arquivo $ rm -f nada.db
Por fim, os comandos de ponto digitados errado no prompt:
sqlite> .tabels Error: unknown command or invalid arguments: "tabels". Enter ".help" for help sqlite> tables ...> ; Parse error: near "tables": syntax error tables ; ^--- error here
O editor tem dois limites próprios. Um comando de ponto vira near ".": syntax error (tabela da seção 2). E um SQL que nunca termina, como uma CTE recursiva sem LIMIT, é interrompido depois de uns 4 segundos com a mensagem interrupted ("interrompido"). No terminal, o mesmo SQL ficaria rodando até você apertar Ctrl+C.
8. Os erros que não dão erro
Os piores erros são os que o SQLite não acusa: a consulta roda, mostra um resultado, e o resultado está errado. Estes enganam todo iniciante pelo menos uma vez:
| O que você escreveu | O que esperava | O que o SQLite dá | Por quê | Aula |
|---|---|---|---|---|
WHERE email = NULL | os 3 clientes sem email | 0 linhas | Nada é igual a NULL, nem o próprio NULL: a comparação dá "desconhecido". Use IS NULL. | IS NULL |
WHERE nome = 'ana carvalho lima' | a cliente Ana Carvalho Lima | 0 linhas | O = diferencia maiúsculas de minúsculas. O LIKE não diferencia (nas letras sem acento). | LIKE |
SELECT 7/2 | 3.5 | 3 | Inteiro dividido por inteiro dá inteiro (a parte decimal é jogada fora). Escreva 7/2.0 ou 7 * 1.0 / 2. | Funções Numéricas |
SELECT 1/0 | um erro | NULL | No SQLite, dividir por zero dá NULL, sem erro. | Funções Numéricas |
SELECT 'abc' + 1 | um erro, ou abc1 | 1 | O + só soma números; um texto que não parece número vale 0. Para juntar textos, use ||. | Funções de Texto |
SELECT 'nome' FROM clientes | os nomes dos clientes | a palavra nome repetida 30 vezes | Entre aspas simples, 'nome' é um texto, não a coluna. Nome de coluna vai sem aspas. | Escolhendo Colunas |
UPDATE produtos SET preco = 10; | mudar o preço de um produto | 45 linhas afetadas | Sem WHERE, o comando vale para a tabela inteira. | O Perigo do UPDATE sem WHERE |
Veja três deles de uma vez, rodando de verdade:
SELECT 7/2, 7/2.0, 1/0, 'abc' + 1; SELECT COUNT(*) AS com_igual FROM clientes WHERE email = NULL; SELECT COUNT(*) AS com_is FROM clientes WHERE email IS NULL;
Os códigos numéricos
O número entre parênteses no fim das mensagens do terminal é o código de resultado do SQLite. Programas (em PHP, Python…) costumam olhar esse número em vez do texto. Os que aparecem nesta página:
| Código | Nome | Quer dizer | Exemplos nesta página |
|---|---|---|---|
| 1 | SQLITE_ERROR | erro genérico de SQL | no such table, syntax error… (o terminal não mostra o número) |
| 5 | SQLITE_BUSY | o banco está ocupado (trancado por outro) | database is locked |
| 8 | SQLITE_READONLY | tentativa de escrever num banco somente leitura | attempt to write a readonly database |
| 19 | SQLITE_CONSTRAINT | uma regra da tabela foi quebrada | UNIQUE, NOT NULL, FOREIGN KEY, CHECK |
| 20 | SQLITE_MISMATCH | tipo de dado incompatível | datatype mismatch |
Cada banco escreve as mensagens do seu jeito, mas os erros são os mesmos. O MySQL numera cada mensagem; o PostgreSQL usa o código SQLSTATE do padrão SQL, que é o mais seguro para um programa conferir. Alguns exemplos, das documentações oficiais (MySQL 8.4 e PostgreSQL):
| Erro | SQLite | MySQL (número e mensagem) | PostgreSQL (SQLSTATE) |
|---|---|---|---|
| tabela não existe | no such table | 1146 Table '%s.%s' doesn't exist | 42P01 undefined_table |
| coluna não existe | no such column | 1054 Unknown column '%s' in '%s' | 42703 undefined_column |
| coluna ambígua | ambiguous column name | 1052 Column '%s' in %s is ambiguous | 42702 ambiguous_column |
| erro de sintaxe | syntax error | 1064 %s near '%s' at line %d | 42601 syntax_error |
| valor repetido | UNIQUE constraint failed | 1062 Duplicate entry '%s' for key %d | 23505 unique_violation |
| obrigatório vazio | NOT NULL constraint failed | 1048 Column '%s' cannot be null | 23502 not_null_violation |
| chave estrangeira | FOREIGN KEY constraint failed | 1452 Cannot add or update a child row: a foreign key constraint fails | 23503 foreign_key_violation |
| CHECK | CHECK constraint failed | 3819 Check constraint '%s' is violated. | 23514 check_violation |
| agregada no lugar errado | misuse of aggregate function | 1111 Invalid use of group function | 42803 grouping_error |
| UNION com colunas diferentes | SELECTs to the left and right of UNION… | 1222 The used SELECT statements have a different number of columns | — |
O %s e o %d são os lugares onde o banco põe o nome da tabela, da coluna ou o número da linha. Uma diferença importante: no PostgreSQL, dividir por zero é erro (22012 division_by_zero), e as aspas duplas são sempre nome, nunca texto, como no editor do guia.
Exercícios
1. A Ana rodou SELECT nome FROM produto; e recebeu no such table: produto. O que aconteceu?
2. Qual mensagem o SQLite dá para WHERE cidade = "Teresina"?
3. misuse of aggregate function COUNT() apareceu numa consulta com WHERE COUNT(*) > 2. Qual é o conserto?
4. No terminal, depois de Enter, o prompt virou ...> e nada aconteceu. O que falta, provavelmente?
5. SELECT COUNT(*) FROM clientes WHERE email = NULL; mostrou 0, mas há clientes sem email. Por quê?
6. Traduza a mensagem
Complete: UNIQUE constraint failed: clientes.id quer dizer que o valor da coluna id já na tabela.
Resumo
- No editor, a mensagem sai crua (
no such table: cliente). No terminal, vem com prefixo:Parse error(o comando nem rodou),Runtime error … (19)(parou no meio), ouError: in prepare/Error: steppingcom o SQL na linha de comando. no such table,no such column,ambiguous column name: confira o nome (as tabelas do guia estão no plural) e, num JOIN, diga de qual tabela é a coluna.near "X": syntax error: o erro está em X ou logo antes dele. Vírgula sobrando, palavra errada, partes fora de ordem.- Texto vai entre aspas simples. Aspas duplas são para nomes, e dão
no such column: "…". … constraint failed: o comando estava certo, os dados quebraram uma regra da tabela (UNIQUE, NOT NULL, FOREIGN KEY, CHECK). Nosqlite3, a chave estrangeira só é checada comPRAGMA foreign_keys = ON.- Agregada no
WHEREdámisuse of aggregate: filtre grupos comHAVING. - Cuidado com o que não dá erro:
= NULL,7/2,1/0,'abc' + 1e oUPDATEsemWHERE.