Retour au cours

data / sql

Modifier les données : INSERT, UPDATE, DELETE

Leçon 71 exercice

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'un WHERE
  • Supprimer des lignes avec DELETE en 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 SELECT de vérification avant tout UPDATE/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.

InstructionRisqueRéflexe de sécurité
INSERTFaible (ajoute seulement)Vérifier les colonnes obligatoires (NOT NULL)
UPDATEMoyen à élevéToujours tester le WHERE via un SELECT d'abord
DELETEÉlevé, parfois irréversibleSELECT 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

sql
-- 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 attendu

Résumé

  • INSERT multi-lignes est bien plus performant que N INSERT séparés.
  • UPDATE/DELETE sans WHERE affectent TOUTES les lignes : toujours tester d'abord avec un SELECT équivalent.
  • ON CONFLICT ... DO UPDATE (upsert) évite un aller-retour SELECT puis INSERT/UPDATE.
  • TRUNCATE est plus rapide que DELETE sans condition mais n'est pas toujours transactionnellement annulable selon le SGBD.

Exercices pratiques

1 disponible
1

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.

Résoudre l’exercice →