data / sql
Modifier les données : INSERT, UPDATE, DELETE
Explication
Ce que vous allez apprendre
- Ajouter des lignes avec
INSERT, y compris en une seule requête multi-lignes - Modifier des lignes existantes avec
UPDATE, toujours accompagné d'unWHERE - Supprimer des lignes avec
DELETEen toute sécurité - Utiliser
ON CONFLICT ... DO UPDATE(upsert) pour insérer ou mettre à jour en une requête - Adopter le réflexe professionnel du
SELECTde vérification avant toutUPDATE/DELETE
Dans quel contexte ?
Un développeur doit appliquer une remise de 10% sur tous les produits de la catégorie 'audio' dans la table produits d'une boutique en ligne en production. Un simple oubli du WHERE categorie = 'audio' dans son UPDATE changerait le prix de TOUS les produits du magasin en quelques millisecondes - un incident classique que cette leçon apprend à éviter.
D'abord, un changement de perspective
Jusqu'ici, toutes les leçons interrogeaient des données déjà présentes. Mais une base de données vit : des clients s'inscrivent, des commandes sont passées. Il faut donc aussi savoir écrire, pas seulement lire.
Le verbe le plus sûr : INSERT
INSERT ajoute de nouvelles lignes. C'est le plus sûr des trois verbes de cette leçon, car il ne touche jamais aux données déjà présentes : au pire, on ajoute une ligne en trop.
Un cran plus risqué : UPDATE
UPDATE modifie des lignes déjà existantes. Ici, une erreur de ciblage devient sérieuse : elle écrase silencieusement une valeur correcte par une valeur fausse, sans prévenir personne.
Le plus dangereux : DELETE
DELETE supprime des lignes. Une erreur à ce niveau fait disparaître des données, parfois définitivement. Plus on avance dans cette liste de trois verbes, plus la prudence doit augmenter.
Le piège numéro un à connaître absolument
UPDATE produits SET prix = prix * 0.9; sans WHERE ne baisse pas le prix d'UN produit : il baisse le prix de TOUS les produits de la table, d'un coup. C'est l'une des erreurs les plus redoutées en production.
Piège fréquent
Un DELETE FROM commandes; sans WHERE, lancé par erreur sur la base de production au lieu de la base de test, vide entièrement la table en une fraction de seconde. Sans sauvegarde récente, ces données sont perdues définitivement.
Le réflexe professionnel qui évite ce piège
Avant d'exécuter un UPDATE ou un DELETE, on écrit d'abord le SELECT équivalent avec la même clause WHERE. On vérifie que les bonnes lignes — et seulement elles — apparaissent. Ensuite seulement, on remplace le SELECT par l'instruction de modification.
| Instruction | Risque | Réflexe de sécurité |
|---|---|---|
INSERT | Faible (ajoute seulement) | Vérifier les colonnes obligatoires (NOT NULL) |
UPDATE | Moyen à élevé | Toujours tester le WHERE via un SELECT d'abord |
DELETE | Élevé, parfois irréversible | SELECT de vérification + transaction (BEGIN/COMMIT) |
Bonne pratique
Encapsule tes UPDATE/DELETE sensibles dans une transaction (BEGIN ... SELECT de contrôle ... COMMIT ou ROLLBACK) pour pouvoir annuler à la moindre surprise, comme montré en fin de la leçon suivante sur les transactions.
Pour aller plus loin : l'upsert
Une fois ces trois verbes maîtrisés, il existe un raccourci pratique : l'upsert (contraction d'update et insert). Il insère une ligne, ou la met à jour si elle existe déjà, évitant une vérification manuelle préalable.
Et la suite
Cette leçon introduit la modification des données ; la suivante, sur les contraintes, montre comment empêcher ces modifications de produire des données incohérentes.
Commandes & code
INSERT, UPDATE, DELETE
-- INSERT simple
INSERT INTO produits (nom, prix, categorie, stock)
VALUES ('Clavier mécanique', 89.99, 'informatique', 50);
-- INSERT multi-lignes (une seule requête, plus performant que N INSERT)
INSERT INTO produits (nom, prix, categorie, stock) VALUES
('Souris sans fil', 29.99, 'informatique', 120),
('Écran 27"', 249.00, 'informatique', 30),
('Casque audio', 59.90, 'audio', 75);
-- INSERT ... SELECT : copier depuis une autre table/requête
INSERT INTO produits_archive (nom, prix, categorie)
SELECT nom, prix, categorie FROM produits WHERE stock = 0;
-- RETURNING : récupérer les lignes insérées (PostgreSQL, SQLite)
INSERT INTO produits (nom, prix) VALUES ('Webcam HD', 45.00) RETURNING id, cree_le;
-- UPSERT : insérer, ou mettre à jour si la clé existe déjà
INSERT INTO produits (id, nom, stock)
VALUES (17, 'Clavier mécanique', 45)
ON CONFLICT (id) DO UPDATE SET stock = EXCLUDED.stock; -- PostgreSQL/SQLite
-- Équivalent MySQL
INSERT INTO produits (id, nom, stock) VALUES (17, 'Clavier mécanique', 45)
ON DUPLICATE KEY UPDATE stock = VALUES(stock);
-- UPDATE : toujours avec WHERE, sinon TOUTES les lignes sont modifiées
UPDATE produits SET prix = prix * 0.9 WHERE categorie = 'audio'; -- -10% sur l'audio
-- UPDATE avec plusieurs colonnes
UPDATE produits
SET stock = stock - 1, derniere_vente = CURRENT_TIMESTAMP
WHERE id = 17;
-- UPDATE avec sous-requête corrélée
UPDATE produits p
SET prix = prix * 1.05
WHERE p.categorie IN (
SELECT categorie FROM categories WHERE tendance = TRUE
);
-- UPDATE avec JOIN (syntaxe PostgreSQL : FROM)
UPDATE commandes co
SET statut = 'client_vip'
FROM clients c
WHERE c.id = co.client_id AND c.total_achats > 10000;
-- DELETE : toujours avec WHERE
DELETE FROM produits WHERE stock = 0 AND categorie = 'obsolete';
-- DELETE avec sous-requête
DELETE FROM commandes
WHERE client_id IN (SELECT id FROM clients WHERE est_banni = TRUE);
-- TRUNCATE : vide une table entière, très rapide, ne déclenche pas les triggers par ligne
TRUNCATE TABLE logs_temporaires;
-- Transaction de sécurité : tester avant de committer
BEGIN;
UPDATE produits SET prix = prix * 1.1 WHERE categorie = 'informatique';
-- vérifier le résultat avec un SELECT avant de valider
SELECT nom, prix FROM produits WHERE categorie = 'informatique';
COMMIT; -- ou ROLLBACK; si le résultat n'est pas celui attenduRésumé
INSERTmulti-lignes est bien plus performant que NINSERTséparés.UPDATE/DELETEsansWHEREaffectent TOUTES les lignes : toujours tester d'abord avec unSELECTéquivalent.ON CONFLICT ... DO UPDATE(upsert) évite un aller-retour SELECT puis INSERT/UPDATE.TRUNCATEest plus rapide queDELETEsans condition mais n'est pas toujours transactionnellement annulable selon le SGBD.
Exercices pratiques
Mission : appliquer une remise sans faire fondre tout le catalogue
Objectif : Écrire un UPDATE ciblé en toute sécurité et un upsert, après avoir compris le danger d'un WHERE manquant.
Contexte
On te demande d'appliquer une remise de 10% sur tous les produits de la catégorie audio dans la table produits d'une boutique en production. Un développeur junior de l'équipe a failli exécuter UPDATE produits SET prix = prix * 0.9; sans filtre la semaine dernière, repéré de justesse en review. Tu dois montrer la bonne méthode et l'appliquer.