⌂ Bases de données
Fiche 8 sur 12

Ajouter, modifier, supprimer des données

Remplir la base : INSERT, UPDATE, DELETE.

Après cette fiche, vous saurez :

1INSERT : ajouter des lignes

INSERT INTO auteurs (nom, prenom, nationalite)
VALUES ('Zola', 'Émile', 'Française');
MorceauRôle
INSERT INTO auteursDans quelle table
(nom, prenom, nationalite)Quelles colonnes on remplit
VALUES (…)Les valeurs, dans le même ordre

Attention

Le texte et les dates vont entre apostrophes simples.

'Zola'          -- du texte  : apostrophes
'2026-09-12'    -- une date  : apostrophes, format AAAA-MM-JJ
1885            -- un nombre : pas d'apostrophes
true            -- un booléen : pas d'apostrophes

Attention, ce sont des apostrophes simples ', pas les guillemets doubles ". En SQL, les guillemets doubles servent à autre chose : ils désignent des noms de colonnes.

Et pour une apostrophe dans le texte ? On la double :

INSERT INTO livres (titre) VALUES ('L''Assommoir');

On ne remplit pas la clé primaire

Grâce à GENERATED ALWAYS AS IDENTITY, PostgreSQL attribue le numéro. Ne le mettez pas dans la liste des colonnes : il le refuserait.

Insérer plusieurs lignes d'un coup

INSERT INTO auteurs (nom, prenom, nationalite) VALUES
('Zola', 'Émile', 'Française'),
('Simenon', 'Georges', 'Belge'),
('Nothomb', 'Amélie', 'Belge'),
('Saint-Exupéry', 'Antoine de', 'Française');

Une seule commande, quatre lignes. Séparées par des virgules, point-virgule à la fin. C'est plus rapide et plus lisible que quatre INSERT.

À retenir

Les colonnes non citées prennent leur valeur par défaut.

INSERT INTO lecteurs (nom, prenom) VALUES ('Dupuis', 'Camille');

adresse et telephone seront NULL. date_inscription prendra la date du jour, grâce au DEFAULT CURRENT_DATE.

2UPDATE : modifier

UPDATE lecteurs
SET adresse = 'rue Haute 5'
WHERE num_lecteur = 1;

Trois parties, toujours les mêmes :

On peut modifier plusieurs colonnes à la fois :

UPDATE lecteurs
SET adresse = 'rue Haute 5',
    telephone = '0498 11 22 33'
WHERE num_lecteur = 1;

Attention

Sans WHERE, UPDATE modifie TOUTES les lignes.

UPDATE lecteurs SET adresse = 'rue Haute 5';

Tous les lecteurs de la base habitent maintenant à la même adresse. Il n'y a pas d'annulation.

La méthode qui sauve : écrivez d'abord un SELECT avec le même WHERE, vérifiez les lignes affichées, puis seulement transformez-le en UPDATE.

-- 1. Je vérifie ce que je vais toucher
SELECT * FROM lecteurs WHERE num_lecteur = 1;

-- 2. Seulement ensuite, je modifie
UPDATE lecteurs SET adresse = 'rue Haute 5' WHERE num_lecteur = 1;

Modifier à partir de la valeur actuelle

-- Enregistrer le retour d'un livre
UPDATE emprunts
SET date_retour = CURRENT_DATE
WHERE num_emprunt = 3;

-- Prolonger tous les emprunts de 7 jours
UPDATE emprunts
SET date_prevue = date_prevue + 7
WHERE date_retour IS NULL;

La deuxième requête utilise l'ancienne valeur pour calculer la nouvelle, exactement comme hp = hp - 2 en programmation.

3DELETE : supprimer

DELETE FROM emprunts
WHERE num_emprunt = 3;

Attention

Sans WHERE, DELETE vide toute la table.

DELETE FROM emprunts;

C'est la commande la plus dangereuse du SQL, et elle ne demande aucune confirmation.

Le même réflexe s'applique : SELECT d'abord, DELETE ensuite.

CommandeEffetLa table existe encore ?
DELETE FROM t WHERE …Supprime certaines lignesOui
DELETE FROM t;Supprime toutes les lignesOui, vide
TRUNCATE TABLE t;Vide la table, plus rapideOui, vide
DROP TABLE t;Supprime la table elle-mêmeNon

4L'ordre de remplissage

Comme pour la création, l'ordre compte. On ne peut pas insérer un livre qui pointe vers un auteur inexistant.

À retenir

On remplit dans le même ordre qu'on a créé :

  1. auteurs et lecteurs
  2. livres — les auteurs existent maintenant
  3. emprunts — les lecteurs et les livres existent

Et on supprime dans l'ordre inverse.

Le jeu de données de la bibliothèque

INSERT INTO auteurs (nom, prenom, nationalite) VALUES
('Zola', 'Émile', 'Française'),
('Simenon', 'Georges', 'Belge'),
('Nothomb', 'Amélie', 'Belge'),
('Saint-Exupéry', 'Antoine de', 'Française');

INSERT INTO lecteurs (nom, prenom, adresse, telephone) VALUES
('Dupuis', 'Camille', 'rue de la Station 12, Binche', '0470 12 34 56'),
('Martin', 'Sofia', 'rue Haute 5, Binche', '0498 11 22 33'),
('Benali', 'Karim', 'chaussée de Mons 44, Binche', '0475 22 33 44');

INSERT INTO livres (titre, annee, isbn, num_auteur) VALUES
('Germinal', 1885, '978-2070413157', 1),
('L''Assommoir', 1877, '978-2070413164', 1),
('Le Chien jaune', 1931, '978-2253142201', 2),
('Stupeur et tremblements', 1999, '978-2253150718', 3),
('Le Petit Prince', 1943, '978-2070612758', 4);

INSERT INTO emprunts (date_emprunt, date_prevue, date_retour, num_lecteur, num_livre) VALUES
('2026-09-01', '2026-09-22', '2026-09-15', 1, 1),
('2026-09-05', '2026-09-26', NULL, 1, 3),
('2026-09-10', '2026-10-01', NULL, 2, 2),
('2026-08-15', '2026-09-05', NULL, 3, 5);

Gardez ce script avec celui de la fiche 7. Les trois fiches suivantes s'appuient dessus.

À retenir

Le dernier emprunt date du 15 août, avec un retour prévu le 5 septembre, et date_retour vide.

Ce livre est donc en retard. C'est volontaire : il servira à construire l'état de sortie de la fiche 12.

→Exercices

1Remplir la baseRecopier
  1. Exécutez le script de la section 4 dans votre base.
  2. Vérifiez avec SELECT * FROM auteurs; puis pour chaque table.
  3. Combien de lignes dans chaque table ?
  4. Regardez la colonne date_inscription des lecteurs. Que contient-elle, et pourquoi ?

Solution

3. 4 auteurs, 3 lecteurs, 5 livres, 4 emprunts.

4. Elle contient la date d'aujourd'hui, alors qu'on ne l'a jamais fournie.

C'est le DEFAULT CURRENT_DATE de la fiche 6 qui a joué. La colonne n'était pas dans la liste de l'INSERT, donc PostgreSQL a appliqué la valeur par défaut.

À observer aussi : les num_auteur valent 1, 2, 3, 4 sans qu'on les ait donnés. C'est GENERATED ALWAYS AS IDENTITY.

Et le titre L''Assommoir s'affiche bien L'Assommoir avec une seule apostrophe. La double apostrophe n'existe que dans le script.

2Modifier et supprimer prudemmentModifier

Pour chaque tâche, écrivez d'abord le SELECT de vérification, puis la commande.

  1. Karim Benali a déménagé au « boulevard Bonaire 8, Binche ».
  2. Le livre Le Petit Prince a été rendu aujourd'hui.
  3. Tous les emprunts non rendus sont prolongés de 14 jours.
  4. Supprimez l'emprunt numéro 1.
  5. Essayez de supprimer le lecteur numéro 1. Que se passe-t-il ?

Solution

-- 1. Déménagement
SELECT * FROM lecteurs WHERE nom = 'Benali';

UPDATE lecteurs
SET adresse = 'boulevard Bonaire 8, Binche'
WHERE num_lecteur = 3;

-- 2. Retour du Petit Prince (emprunt n°4)
SELECT * FROM emprunts WHERE num_livre = 5;

UPDATE emprunts
SET date_retour = CURRENT_DATE
WHERE num_emprunt = 4;

-- 3. Prolongation des emprunts en cours
SELECT * FROM emprunts WHERE date_retour IS NULL;

UPDATE emprunts
SET date_prevue = date_prevue + 14
WHERE date_retour IS NULL;

-- 4. Suppression
SELECT * FROM emprunts WHERE num_emprunt = 1;

DELETE FROM emprunts WHERE num_emprunt = 1;

-- 5. Suppression du lecteur 1
DELETE FROM lecteurs WHERE num_lecteur = 1;

5. Échoue.

ERROR: update or delete on table "lecteurs" violates foreign key constraint "fk_emprunts_lecteur" on table "emprunts"
DETAIL: Key (num_lecteur)=(1) is still referenced from table "emprunts".

Camille a encore l'emprunt n°2 en cours. La clé étrangère fait son travail : elle empêche de créer un emprunt orphelin.

Pour vraiment le supprimer, il faudrait d'abord effacer ses emprunts. Mais faut-il le faire ? Dans une bibliothèque, on désactive un lecteur, on ne l'efface pas. C'est ce qu'on appelle une suppression logique : on ajouterait une colonne actif BOOLEAN DEFAULT true et on la passerait à false.

Un point sur la question 3 : WHERE date_retour IS NULL et non WHERE date_retour = NULL. On ne compare jamais NULL avec =. Nous verrons pourquoi à la fiche 9.

3Remplir votre baseCréer

Reprenez votre base de la fiche 7.

  1. Écrivez un script qui insère au moins 4 lignes dans chaque table.
  2. Respectez l'ordre imposé par les clés étrangères.
  3. Prévoyez au moins une ligne « intéressante » : un cas limite, une donnée manquante, quelque chose qui servira plus tard à un filtre.
  4. Testez qu'une insertion incorrecte est bien refusée.

Solution

INSERT INTO patients (nom, prenom, date_naissance, telephone, numero_national) VALUES
('Dupuis', 'Camille', '1984-03-12', '0470 12 34 56', '84031212345'),
('Martin', 'Sofia', '1991-07-25', '0498 11 22 33', '91072554321'),
('Benali', 'Karim', '1976-11-03', '0475 22 33 44', '76110398765'),
('Leroy', 'Jean', '2015-01-30', NULL, '15013011223');

INSERT INTO medecins (nom, prenom, specialite, numero_inami) VALUES
('Moreau', 'Anne', 'Médecine générale', '1-23456-78-901'),
('Dubois', 'Marc', 'Dermatologie', '1-34567-89-012'),
('Lambert', 'Julie', 'Pédiatrie', '1-45678-90-123');

INSERT INTO consultations (date_consult, heure, motif, montant, num_patient, num_medecin) VALUES
('2026-09-01', '09:30', 'Contrôle annuel', 30.00, 1, 1),
('2026-09-01', '10:15', 'Eczéma', 45.00, 2, 2),
('2026-09-03', '14:00', 'Vaccination', 25.00, 4, 3),
('2026-09-05', '11:00', 'Renouvellement ordonnance', 30.00, 1, 1),
('2026-09-08', '16:30', NULL, 30.00, 3, 1);

Les lignes intéressantes prévues :

  • Jean Leroy n'a pas de téléphone — un enfant. Servira à tester IS NULL.
  • La dernière consultation n'a pas de motif. Même usage.
  • Camille a deux consultations chez le même médecin. Servira aux comptages de la fiche 11.
  • Le docteur Dubois n'a qu'une consultation, Lambert aussi. Servira aux jointures externes de la fiche 10.

Le test d'insertion incorrecte :

INSERT INTO consultations (date_consult, montant, num_patient, num_medecin)
VALUES ('2026-09-10', 30.00, 99, 1);
ERROR: insert or update on table "consultations" violates foreign key constraint "fk_consultations_patient"

Un conseil pour la suite : prévoyez toujours quelques lignes « anormales » dans vos jeux de test. Une base où tout est parfaitement rempli ne permet pas de tester les cas réels — et ce sont eux qui font échouer les programmes.

Je sais faire

Une case qui coince ? Relisez la partie concernée avant de passer à la fiche suivante.

← Fiche 7 Fiche 9 : Interroger : le SELECT →