Menu

UPDATE no SQLite: WHERE, várias colunas e UPDATE FROM

Como alterar linhas existentes no SQLite: sintaxe do UPDATE, a cláusula WHERE que evita estragos, atualização de várias colunas e UPDATE ... FROM entre tabelas.

Esta página tem editores executáveis — edite, execute e veja a saída na hora.

UPDATE altera registros existentes

Enquanto o INSERT cria novos registros, o UPDATE serve para modificar linhas que já estão na tabela. A estrutura é curta e vale a pena gravar:

UPDATE table_name
SET column = value
WHERE condition;

Um exemplo prático:

SET define o que muda. WHERE define quais linhas. O resto da tabela fica intocado.

O WHERE no UPDATE não é opcional na prática

Tecnicamente, o WHERE é opcional. Na prática, esquecer dele é como o dev júnior estraga a tarde inteira:

UPDATE users SET status = 'inactive';
-- todos os usuários agora estão inativos

Sem filtro, toda linha vira candidata. O SQLite obedece em silêncio. Crie o hábito de escrever o WHERE antes do SET — só essa troca de ordem já evita um monte de dor de cabeça.

Na dúvida se o seu WHERE está certo, teste a mesma condição num SELECT antes:

Mesma condição, duas instruções. O SELECT funciona como um ensaio antes de aplicar a mudança.

Atualizando várias colunas de uma vez

Para atualizar várias colunas no SQLite, basta separar as atribuições com vírgula dentro de um único SET. Um SET só, várias colunas:

Uma ida e volta ao banco, uma linha alterada, três colunas atualizadas. Não escreva três comandos UPDATE separados quando um único resolve.

Expressões à direita do =

O valor depois do = não precisa ser um literal. Pode ser qualquer expressão — inclusive uma que use o valor atual da própria coluna:

price * 1.10 lê o preço atual, multiplica e grava o resultado de volta. O SQLite avalia o lado direito usando os valores atuais da linha antes que qualquer atribuição deste comando entre em vigor, então dá pra referenciar várias colunas sem dor de cabeça:

UPDATE products SET price = price * 1.10, stock = stock + price;
-- 'price' no lado direito aqui é o preço ANTIGO, não o que acabou de ser atualizado.

UPDATE ... FROM: trazendo valores de outra tabela

A partir do SQLite 3.33, o UPDATE passou a aceitar a cláusula FROM, ideal para fazer update entre tabelas. Essa é a forma mais limpa de sincronizar dados de uma tabela para outra:

A subquery calcula os totais por cliente, e o UPDATE externo junta esses resultados de volta na tabela customers pelo id. Sem o UPDATE ... FROM, você teria que escrever uma subquery correlacionada para cada coluna — bem mais verboso.

Algumas regras importantes:

  • A tabela alvo vem depois do UPDATE, não na lista do FROM.
  • Quem faz o join é a cláusula WHERE — aqui não existe a palavra-chave ON.
  • Se o join puder casar mais de uma linha no FROM, o resultado fica indefinido. Garanta que suas chaves de join produzam no máximo uma correspondência por linha alvo.

RETURNING: veja o que foi alterado

A partir da versão 3.35, o SQLite permite que o UPDATE retorne as linhas modificadas na mesma instrução. É bem útil quando sua aplicação precisa dos valores já atualizados sem ter que disparar um SELECT depois:

Você recebe de volta as linhas que foram efetivamente alteradas, já com os novos valores. Isso economiza uma ida e volta ao banco e elimina uma série de condições de corrida em código concorrente. Mais adiante neste capítulo tem uma página inteira só sobre o RETURNING.

UPDATE OR REPLACE: lidando com conflitos de constraint

Se o seu UPDATE acabar violando uma constraint UNIQUE, o comportamento padrão é abortar a instrução e estourar um erro. A cláusula OR permite escolher outra política:

As opções são OR ABORT (padrão), OR REPLACE, OR IGNORE, OR FAIL e OR ROLLBACK. O REPLACE é o perigoso — ele apaga a linha conflitante, e isso pode propagar efeitos via chaves estrangeiras. Use apenas quando você realmente quer dizer "se já existe uma linha com esse valor único, joga ela fora".

Para a maioria dos casos de upsert, a sintaxe específica INSERT ... ON CONFLICT deixa a intenção mais clara. Tem uma página só sobre isso.

Envolva updates arriscados em uma transação

Quando você precisa alterar muitas linhas ou executar vários UPDATE que precisam funcionar em conjunto, coloque tudo dentro de uma transação. Se algo der errado, dá pra reverter ao estado anterior:

Se o segundo comando falhar (digamos, por causa de uma constraint), o ROLLBACK desfaz o primeiro. Sem transação, você ficaria com uma transferência pela metade — a Ada com 25 a menos e o Boris do mesmo jeito. Transações terão um capítulo só pra elas mais adiante; por enquanto, basta saber que existem e que updates em massa quase sempre devem ficar dentro de uma.

Armadilhas comuns

Uma lista curta do que costuma pegar quem está começando:

  • Esquecer o WHERE — atualiza todas as linhas. Leia o comando em voz alta antes de rodar.
  • Operador errado no WHEREWHERE status = NULL não casa com nada. Use IS NULL. Vamos detalhar isso na página de operadores.
  • Update com subquery que retorna mais de uma linha quando você espera só uma. Use LIMIT 1 ou agregue a subquery, senão vai dar erro ou trazer resultado inesperado.
  • Confundir UPDATE OR REPLACE com UPSERT. O OR REPLACE apaga as linhas que entram em conflito. Já o INSERT ... ON CONFLICT DO UPDATE altera essas linhas no lugar. São operações diferentes.

A seguir: DELETE

O UPDATE altera linhas; o DELETE remove. A mesma disciplina com o WHERE se aplica — e o mesmo hábito de "rodar um SELECT antes" vai te livrar dos mesmos tipos de desastre. É o tema da próxima página.

Perguntas frequentes

Qual é a sintaxe básica do UPDATE no SQLite?

UPDATE nome_tabela SET coluna = valor WHERE condição;. No SET você lista as colunas que quer alterar e os novos valores. O WHERE define quais linhas serão afetadas — esqueceu o WHERE? Pronto, atualizou a tabela inteira.

Como atualizar várias colunas em um único comando?

Basta separar as atribuições por vírgula dentro do SET: UPDATE users SET name = 'Ada', email = 'ada@x.com' WHERE id = 1;. Um comando só, uma ida ao banco, uma linha alterada. Não precisa repetir o SET para cada coluna.

Dá para atualizar uma tabela a partir de outra no SQLite?

Dá sim — o UPDATE ... FROM (disponível desde o SQLite 3.33) permite juntar outra tabela ou subconsulta no update. A forma é: UPDATE destino SET col = origem.col FROM origem WHERE destino.id = origem.id;. É o jeito mais limpo de copiar valores entre tabelas.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR