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.

Como usar esta página
  • 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:

PrefixoOnde apareceQuer 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 comandoO mesmo que Runtime error: falhou ao executar.
Error: unknown command …no prompt sqlite>, depois de um pontoComando de ponto que não existe (veja No terminal).
Um erro para tudo

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êsCausa comumComo resolverAula
no such table: clientenão existe a tabela clienteNome 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: nomeenão existe a coluna nomeeNome 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.idnão existe a coluna clientes.idVocê 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: idnome de coluna ambíguo: idNum 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: abcnão existe a função abcNome 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 existsa tabela clientes já existeCREATE 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 nadaApagar uma tabela que não existe.DROP TABLE IF EXISTS nada; não dá erro.DROP TABLE
duplicate column name: emailnome de coluna repetido: emailALTER 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êsCausa comumComo resolverAula
near "SELEC": syntax errorperto de "SELEC": erro de sintaxePalavra-chave digitada errado.Corrija a palavra: SELECT.SELECT
near "FROM": syntax errorperto de "FROM": erro de sintaxeVírgula sobrando antes do FROM: SELECT nome, FROM clientes.Apague a vírgula depois da última coluna.Escolhendo Colunas
near ";": syntax errorperto de ";": erro de sintaxeO 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 errorperto de "WHERE": erro de sintaxePartes 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 errorperto de "DESC": erro de sintaxePalavra repetida: ORDER BY nome DESC DESC.Apague a repetição.ORDER BY
near ".": syntax errorperto de ".": erro de sintaxeUm 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 inputentrada incompletaO 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
Aspas duplas no texto

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êsCausa comumComo resolverAula
UNIQUE constraint failed: clientes.idrestrição UNIQUE falhou: clientes.idInserir 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.nomerestrição NOT NULL falhou: categorias.nomeColuna 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 failedrestrição de chave estrangeira falhouApontar 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 > 0restrição CHECK falhou: preco > 0O 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_positivorestriçã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 mismatchtipo de dado incompatívelUm 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.nnão dá para guardar um valor TEXT na coluna INTEGER t.nTabela 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)
A chave estrangeira que não reclama

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êsCausa comumComo resolverAula
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 clausefunções agregadas não são permitidas no GROUP BYGROUP 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 querycláusula HAVING numa consulta sem agregaçãoHAVING sem GROUP BY e sem função agregada.Para filtrar linhas, use WHERE.HAVING
DISTINCT aggregates must have exactly one argumentagregadas com DISTINCT precisam de exatamente um argumentogroup_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êsCausa comumComo resolverAula
SELECTs to the left and right of UNION do not have the same number of result columnsos SELECTs à esquerda e à direita do UNION não têm o mesmo número de colunasUm 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 supplieda tabela categorias tem 3 colunas, mas foram dados 2 valoresINSERT 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 columns2 valores para 3 colunasA 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 1a subconsulta devolve 2 colunas; era esperada 1WHERE 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 1o 1º termo do ORDER BY está fora do intervalo: deveria estar entre 1 e 1ORDER 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 1o mesmo, no GROUP BYGROUP 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êsCausa comumComo resolverAula
cannot start a transaction within a transactionnão dá para começar uma transação dentro de outraDois 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 activenão dá para confirmar: nenhuma transação está abertaCOMMIT 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 activenão dá para desfazer: nenhuma transação está abertaROLLBACK 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êsCausa comumComo resolverAula
database is locked (5)o banco está trancadoOutro 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 leituraO 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 clientesO 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 helpcomando desconhecido ou argumentos inválidos: "tabels". Digite .help para ajudaComando de ponto digitado errado.Veja a lista com .help ou na referência dos comandos de ponto.Comandos de Ponto
near "tables": syntax errorperto de "tables": erro de sintaxeEsqueceu 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
E no editor do guia?

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ê escreveuO que esperavaO que o SQLite dáPor quêAula
WHERE email = NULLos 3 clientes sem email0 linhasNada é 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 Lima0 linhasO = diferencia maiúsculas de minúsculas. O LIKE não diferencia (nas letras sem acento).LIKE
SELECT 7/23.53Inteiro 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/0um erroNULLNo SQLite, dividir por zero dá NULL, sem erro.Funções Numéricas
SELECT 'abc' + 1um erro, ou abc11O + 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 clientesos nomes dos clientesa palavra nome repetida 30 vezesEntre 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 produto45 linhas afetadasSem 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ódigoNomeQuer dizerExemplos nesta página
1SQLITE_ERRORerro genérico de SQLno such table, syntax error… (o terminal não mostra o número)
5SQLITE_BUSYo banco está ocupado (trancado por outro)database is locked
8SQLITE_READONLYtentativa de escrever num banco somente leituraattempt to write a readonly database
19SQLITE_CONSTRAINTuma regra da tabela foi quebradaUNIQUE, NOT NULL, FOREIGN KEY, CHECK
20SQLITE_MISMATCHtipo de dado incompatíveldatatype mismatch
Nos outros bancos

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):

ErroSQLiteMySQL (número e mensagem)PostgreSQL (SQLSTATE)
tabela não existeno such table1146 Table '%s.%s' doesn't exist42P01 undefined_table
coluna não existeno such column1054 Unknown column '%s' in '%s'42703 undefined_column
coluna ambíguaambiguous column name1052 Column '%s' in %s is ambiguous42702 ambiguous_column
erro de sintaxesyntax error1064 %s near '%s' at line %d42601 syntax_error
valor repetidoUNIQUE constraint failed1062 Duplicate entry '%s' for key %d23505 unique_violation
obrigatório vazioNOT NULL constraint failed1048 Column '%s' cannot be null23502 not_null_violation
chave estrangeiraFOREIGN KEY constraint failed1452 Cannot add or update a child row: a foreign key constraint fails23503 foreign_key_violation
CHECKCHECK constraint failed3819 Check constraint '%s' is violated.23514 check_violation
agregada no lugar erradomisuse of aggregate function1111 Invalid use of group function42803 grouping_error
UNION com colunas diferentesSELECTs 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), ou Error: in prepare / Error: stepping com 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). No sqlite3, a chave estrangeira só é checada com PRAGMA foreign_keys = ON.
  • Agregada no WHERE dá misuse of aggregate: filtre grupos com HAVING.
  • Cuidado com o que não dá erro: = NULL, 7/2, 1/0, 'abc' + 1 e o UPDATE sem WHERE.