SQL Pratique
INSERT en SQL : insérer des données sans erreur
9 min de lecture

INSERT en SQL : insérer des données sans erreur

Maîtrisez la commande INSERT en SQL : syntaxes, insertions multiples, sous-requêtes et pièges à éviter. Guide complet avec exemples pratiques.

Avatar de Thomas LeroyThomas Leroy

La commande INSERT est la première instruction que vous utilisez pour peupler une base de données. Bien que sa syntaxe de base soit simple, elle recèle des variantes puissantes — et des pièges courants — que les candidats sous-estiment en entretien. Que vous ayez à insérer une seule ligne, des milliers d'enregistrements en batch, ou les résultats d'une requête SELECT, maîtriser INSERT INTO correctement fait la différence entre un code fragile et un code production-ready.

Ce guide couvre toutes les formes de la commande INSERT, les erreurs classiques à éviter, et les optimisations à connaître pour un entretien technique SQL.

📌 Ce qu'il faut retenir

  • INSERT INTO ... VALUES est la forme de base ; toujours lister les colonnes explicitement
  • L'insertion multi-lignes en une seule requête est nettement plus performante que les insertions unitaires
  • INSERT INTO ... SELECT permet de copier ou transformer des données directement en base
  • Les contraintes (NOT NULL, UNIQUE, FK) sont vérifiées à l'insertion : anticiper les erreurs de contrainte

La syntaxe de base de INSERT INTO

La forme minimale de INSERT s'écrit en deux parties : la déclaration de la cible, et les valeurs à insérer.

INSERT INTO employes (prenom, nom, departement_id, salaire)
VALUES ('Alice', 'Martin', 3, 45000);

Ici, la liste des colonnes entre parenthèses est facultative syntaxiquement, mais obligatoire en pratique. Omettre les colonnes force l'ordre de la définition de la table, ce qui rend le code cassant dès qu'un ALTER TABLE ajoute ou réordonne une colonne.

La valeur associée à chaque colonne doit respecter le type déclaré : une chaîne pour un VARCHAR, un entier pour un INT, et NULL pour les colonnes qui l'autorisent. Toute violation déclenchera une erreur avant même que la ligne soit écrite.

⚠️ Attention

Ne jamais omettre la liste des colonnes dans un INSERT en production. Un ajout de colonne en base suffit à faire planter silencieusement ou bruyamment tous vos scripts d'alimentation.

Insérer plusieurs lignes en une seule requête

Depuis SQL:2003, la plupart des SGBD acceptent l'insertion multi-lignes dans un unique INSERT. C'est la façon la plus efficace de charger des données en lot.

INSERT INTO employes (prenom, nom, departement_id, salaire)
VALUES
  ('Bob',     'Dupont',  1, 38000),
  ('Claire',  'Leroy',   2, 52000),
  ('David',   'Morin',   1, 41000);

Cette syntaxe réduit drastiquement le nombre d'allers-retours réseau entre l'application et la base. Sur un chargement de 10 000 lignes, passer de 10 000 requêtes unitaires à quelques centaines de requêtes multi-lignes peut diviser le temps d'exécution par un facteur 10 à 50.

La limite pratique du nombre de lignes par INSERT dépend du SGBD et de la taille des données : PostgreSQL et MySQL gèrent sans problème des milliers de lignes par requête, mais il est prudent de découper au-delà de 5 000 lignes pour éviter les timeouts et faciliter la gestion des erreurs.

INSERT INTO ... SELECT : copier et transformer à la volée

La forme INSERT INTO ... SELECT est l'une des plus utiles en data engineering. Elle insère directement les résultats d'une requête SELECT dans une table cible, sans passer par l'application cliente.

INSERT INTO employes_archive (prenom, nom, departement_id, salaire, archive_date)
SELECT prenom, nom, departement_id, salaire, CURRENT_DATE
FROM employes
WHERE date_depart IS NOT NULL;

Cette technique est centrale pour les pipelines ETL légers : alimenter une table de staging, archiver des lignes expirées, ou dédupliquer un jeu de données. Elle évite un aller-retour applicatif coûteux et permet d'exploiter toute la puissance de SQL (JOINs, fonctions d'agrégat, CTEs) dans la requête source.

Pour aller plus loin sur la structuration de requêtes complexes, consultez l'article sur les CTE SQL : Common Table Expressions — elles s'intègrent parfaitement avec INSERT INTO ... SELECT.

💡 Bon à savoir

Avec PostgreSQL, vous pouvez utiliser INSERT INTO ... SELECT combiné à un WITH (CTE) pour pré-calculer des transformations complexes avant insertion, le tout en une seule instruction atomique.

Comparaison des variantes INSERT selon les SGBD

Les syntaxes diffèrent légèrement selon le moteur utilisé. Voici un tableau de référence rapide pour les 4 principaux SGBD rencontrés en entretien.

Fonctionnalité PostgreSQL MySQL / MariaDB SQLite SQL Server
INSERT multi-lignes
INSERT ... SELECT
INSERT ... RETURNING ❌ (utiliser LAST_INSERT_ID) ✅ (v3.35+) OUTPUT au lieu de RETURNING
INSERT OR IGNORE / ON CONFLICT ON CONFLICT DO NOTHING INSERT IGNORE INSERT OR IGNORE pas d'équivalent natif simple
UPSERT natif ON CONFLICT DO UPDATE ON DUPLICATE KEY UPDATE INSERT OR REPLACE MERGE

Gérer les conflits : INSERT OR IGNORE et UPSERT

Insérer des données en ignorant les doublons ou en mettant à jour une ligne existante est un besoin fréquent. Les SGBD modernes proposent tous une forme d'upsert (fusion insertion/mise à jour).

Sur PostgreSQL, la clause ON CONFLICT est la plus lisible :

INSERT INTO produits (sku, nom, prix)
VALUES ('ABC123', 'Clavier mécanique', 89.99)
ON CONFLICT (sku)
DO UPDATE SET prix = EXCLUDED.prix, nom = EXCLUDED.nom;

Le mot-clé EXCLUDED fait référence à la ligne qui aurait été insérée. Cette approche est atomique et thread-safe, contrairement à un pattern UPDATE + INSERT séparé qui crée une fenêtre de concurrence.

Sur MySQL, la syntaxe équivalente est ON DUPLICATE KEY UPDATE. En SQL Server, l'instruction MERGE est plus verbeuse mais couvre des cas de réconciliation plus complexes.

L'upsert est très apprécié dans les entretiens axés data engineering car il teste à la fois votre compréhension des contraintes et votre sens des cas limites de concurrence.

Les erreurs de contrainte les plus fréquentes

Lorsqu'un INSERT échoue, l'erreur provient presque toujours d'une violation de contrainte. Voici les 3 cas les plus courants.

Violation de clé primaire ou UNIQUE : vous tentez d'insérer une valeur déjà présente dans une colonne indexée comme unique. Solution : utiliser ON CONFLICT ou vérifier l'existence avant insertion.

Violation de clé étrangère : la valeur de departement_id que vous insérez n'existe pas dans la table departements. Toujours insérer dans le bon ordre : la table parente avant la table enfant.

Violation NOT NULL : une colonne obligatoire reçoit NULL, soit parce que vous l'avez omise de la liste, soit parce que la valeur calculée est NULL. Utiliser COALESCE et NULLIF pour sécuriser vos valeurs avant insertion est une bonne pratique.

La clause RETURNING : récupérer l'ID généré

PostgreSQL et SQLite (v3.35+) permettent de récupérer immédiatement les valeurs générées par un INSERT grâce à RETURNING.

INSERT INTO commandes (client_id, montant, statut)
VALUES (42, 199.90, 'en_attente')
RETURNING id, created_at;

Cette clause est précieuse quand une colonne id est générée automatiquement (SERIAL, IDENTITY) et que vous en avez besoin pour insérer des lignes dans une table liée dans la même transaction. Elle évite un SELECT supplémentaire et garantit que vous récupérez exactement l'ID de la ligne que vous venez de créer.

Sur MySQL, LAST_INSERT_ID() joue le même rôle mais ne s'applique qu'à la dernière insertion de la session, ce qui peut poser problème avec des insertions multi-lignes.

Questions fréquentes

Faut-il toujours spécifier la liste des colonnes dans un INSERT ?

Oui, en pratique. La liste des colonnes est techniquement facultative si vous fournissez une valeur pour chaque colonne dans l'ordre exact de la table — mais cette approche est fragile. Un ALTER TABLE ADD COLUMN ou un simple réordonnancement peut casser silencieusement vos insertions. Toujours nommer explicitement les colonnes est une règle de base du SQL en production.

Quelle est la différence entre INSERT et UPSERT ?

Un INSERT échoue ou est ignoré si une ligne en conflit existe déjà. Un upsert (contraction de update + insert) insère la ligne si elle est nouvelle, ou met à jour la ligne existante selon les règles que vous définissez. En SQL, cela se traduit par ON CONFLICT DO UPDATE (PostgreSQL), ON DUPLICATE KEY UPDATE (MySQL) ou MERGE (SQL Server).

Peut-on insérer des données depuis une autre table avec des transformations ?

Absolument. INSERT INTO ... SELECT accepte n'importe quelle requête SELECT, aussi complexe soit-elle : JOINs, GROUP BY, fonctions de fenêtre, CTEs. C'est l'approche standard pour alimenter des tables de reporting ou d'archive en une seule opération atomique.

Comment éviter les doublons lors d'une insertion en masse ?

Plusieurs stratégies existent : utiliser ON CONFLICT DO NOTHING (PostgreSQL) ou INSERT IGNORE (MySQL) pour ignorer silencieusement les doublons, ou filtrer en amont avec un WHERE NOT EXISTS dans la clause SELECT d'un INSERT INTO ... SELECT. La première option est plus concise ; la seconde donne plus de contrôle sur les données effectivement insérées.

INSERT est-il transactionnel par défaut ?

Cela dépend du SGBD et de la configuration. PostgreSQL enveloppe chaque statement dans une transaction implicite. MySQL avec InnoDB aussi. En revanche, si vous exécutez un INSERT multi-lignes, l'ensemble de l'instruction est atomique : soit toutes les lignes sont insérées, soit aucune (en cas d'erreur). Pour des insertions interdépendantes, utilisez explicitement BEGIN / COMMIT afin de garantir la cohérence.

Conclusion

La commande INSERT est bien plus riche que sa syntaxe de base ne le laisse supposer. Maîtriser les insertions multi-lignes, le pattern INSERT INTO ... SELECT, la gestion des conflits avec ON CONFLICT, et la récupération des IDs générés vous permettra d'écrire un SQL robuste et performant — et d'impressionner votre interlocuteur en entretien technique.

La prochaine étape naturelle est de combiner INSERT avec des transactions explicites pour garantir la cohérence de vos pipelines de données. Entraînez-vous dès maintenant sur SQL Pratique avec des exercices interactifs qui simulent les conditions réelles d'un entretien data.

Prêt à vous entraîner ?

50 exercices SQL interactifs avec éditeur en ligne, chronomètre et feedback IA.

Voir les exercices