Menu

SQLite UPDATE : WHERE, plusieurs colonnes et UPDATE FROM

Modifier des lignes existantes en SQLite : syntaxe d'UPDATE, clause WHERE pour éviter les catastrophes, mise à jour multi-colonnes et UPDATE ... FROM pour croiser des tables.

Cette page contient des éditeurs exécutables — modifiez, exécutez et voyez la sortie instantanément.

UPDATE pour modifier des lignes existantes

Là où INSERT sert à ajouter de nouvelles lignes, UPDATE permet de modifier celles qui sont déjà en base. La syntaxe est concise et mérite d'être retenue par cœur :

UPDATE table_name
SET column = value
WHERE condition;

Un exemple concret :

SET indique ce qui change. WHERE indique quelles lignes. Le reste de la table reste intact.

La clause WHERE : optionnelle en théorie, indispensable en pratique

Techniquement, WHERE est optionnelle. Concrètement, l'oublier est le meilleur moyen pour un dev junior de gâcher son après-midi :

UPDATE users SET status = 'inactive';
-- chaque utilisateur est désormais inactif

Sans filtre, toutes les lignes correspondent. Et SQLite s'exécutera sans broncher. Prenez l'habitude d'écrire le WHERE avant le SET — rien que ce réflexe vous évitera bien des catastrophes.

En cas de doute sur votre WHERE, testez d'abord la même condition avec un SELECT :

Même condition, deux requêtes. Le SELECT te sert de répétition générale.

Modifier plusieurs colonnes en une seule fois

Sépare les affectations par des virgules à l'intérieur d'un seul SET. Un seul SET, plusieurs colonnes mises à jour :

Un seul aller-retour vers la base, une ligne touchée, trois colonnes mises à jour. Inutile d'écrire trois UPDATE séparés quand un seul suffit.

Des expressions à droite du =

La valeur après = n'est pas obligée d'être un littéral. Ça peut être n'importe quelle expression — y compris une qui réutilise la valeur actuelle de la colonne :

price * 1.10 lit le prix actuel, le multiplie, puis réécrit le résultat dans la colonne. SQLite évalue la partie droite à partir des valeurs actuelles de la ligne avant d'appliquer les affectations de cette instruction, ce qui permet de référencer plusieurs colonnes sans crainte :

UPDATE products SET price = price * 1.10, stock = stock + price;
-- 'price' à droite ici correspond à l'ANCIEN prix, pas à celui qui vient d'être mis à jour.

UPDATE ... FROM : récupérer des valeurs depuis une autre table

Depuis SQLite 3.33, la commande UPDATE accepte une clause FROM, ce qui permet de faire des mises à jour entre plusieurs tables. C'est la façon la plus propre de synchroniser des données d'une table à une autre :

La sous-requête calcule les totaux par client ; le UPDATE externe rattache ensuite ces résultats à la table customers via id. Sans UPDATE ... FROM, il faudrait écrire une sous-requête corrélée pour chaque colonne — beaucoup plus verbeux.

Quelques règles à garder en tête :

  • La table cible se place après UPDATE, pas dans le FROM.
  • C'est la clause WHERE qui fait la jointure — il n'y a pas de mot-clé ON ici.
  • Si la jointure peut correspondre à plusieurs lignes dans le FROM, le résultat est indéterminé. Assurez-vous que vos clés de jointure produisent au maximum une correspondance par ligne cible.

RETURNING : voir ce qui a changé

Depuis SQLite 3.35+, on peut faire un UPDATE RETURNING pour récupérer les lignes modifiées dans la même requête. Très pratique quand l'application a besoin des nouvelles valeurs sans relancer un SELECT derrière :

Vous récupérez les lignes réellement modifiées, avec leurs nouvelles valeurs. Cela évite un aller-retour et élimine toute une catégorie de race conditions dans le code concurrent. Une page entière est consacrée à RETURNING plus loin dans ce chapitre.

UPDATE OR REPLACE : gérer les conflits de contraintes

Si votre mise à jour viole une contrainte UNIQUE, le comportement par défaut est d'interrompre l'instruction avec une erreur. La clause OR vous permet de choisir une autre stratégie :

Les options disponibles sont OR ABORT (par défaut), OR REPLACE, OR IGNORE, OR FAIL et OR ROLLBACK. La plus risquée, c'est REPLACE : elle supprime la ligne en conflit, ce qui peut déclencher des cascades via les clés étrangères. À n'utiliser que si vous voulez vraiment dire « s'il existe déjà une ligne avec cette valeur unique, jette-la ».

Pour la plupart des cas de type upsert, la syntaxe dédiée INSERT ... ON CONFLICT est nettement plus claire. Une page entière y est consacrée.

Encadrer les UPDATE risqués dans une transaction

Quand vous modifiez beaucoup de lignes ou que vous enchaînez plusieurs UPDATE qui doivent tous réussir ensemble, regroupez-les dans une transaction. Si quoi que ce soit part en vrille, vous pouvez revenir à l'état initial :

Si la seconde requête échoue (par exemple à cause d'une contrainte), le ROLLBACK annule la première. Sans transaction, vous vous retrouveriez avec un transfert à moitié fait — Ada perd 25, Boris ne reçoit rien. On consacrera tout un chapitre aux transactions plus loin ; pour l'instant, retenez juste qu'elles existent et que les mises à jour en masse devraient presque toujours se faire à l'intérieur d'une transaction.

Les pièges classiques

Voici une petite liste des trucs qui font trébucher tout le monde :

  • Oublier le WHERE — toutes les lignes y passent. Relisez votre requête à voix haute avant de l'exécuter.
  • Mauvais opérateur dans le WHEREWHERE status = NULL ne renvoie rien. Il faut écrire IS NULL. On reviendra là-dessus dans la page sur les opérateurs.
  • Faire un UPDATE avec une sous-requête qui renvoie plusieurs lignes alors que vous en attendiez une seule. Utilisez LIMIT 1 ou une fonction d'agrégation, sinon vous aurez droit à des erreurs ou à des résultats inattendus.
  • Confondre UPDATE OR REPLACE et UPSERT. OR REPLACE supprime les lignes en conflit. INSERT ... ON CONFLICT DO UPDATE les modifie sur place. Ce sont deux opérations différentes.

La suite : DELETE

UPDATE modifie des lignes ; DELETE les supprime. La même rigueur sur le WHERE s'applique — et le même réflexe de « lancer un SELECT d'abord » vous évitera les mêmes catastrophes. C'est le sujet de la prochaine page.

Questions fréquentes

Quelle est la syntaxe de base d'UPDATE en SQLite ?

UPDATE nom_table SET colonne = valeur WHERE condition;. La clause SET liste les colonnes à modifier avec leurs nouvelles valeurs, et WHERE filtre les lignes concernées. Attention : si vous oubliez le WHERE, toutes les lignes de la table sont mises à jour.

Comment modifier plusieurs colonnes en une seule requête ?

Il suffit de séparer les affectations par des virgules dans la clause SET : UPDATE users SET name = 'Ada', email = 'ada@x.com' WHERE id = 1;. Une seule requête, un seul aller-retour vers la base, une ligne modifiée. Inutile de répéter SET pour chaque colonne.

SQLite permet-il de mettre à jour une table depuis une autre ?

Oui — UPDATE ... FROM (disponible depuis SQLite 3.33) permet de joindre une autre table ou une sous-requête dans l'UPDATE. La syntaxe est : UPDATE cible SET col = source.col FROM source WHERE cible.id = source.id;. C'est la façon la plus propre de recopier des valeurs entre tables.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER