Dans cet article
- La commande ALTER TABLE … ADD permet d’ajouter une colonne à une table existante en une seule instruction
- Vous pouvez insérer plusieurs colonnes en une seule requête sur SQL Server, PostgreSQL et MySQL
- Définir une valeur par défaut avec DEFAULT évite les valeurs NULL sur les lignes déjà présentes
- La clause AFTER (MySQL) positionne la colonne à un endroit précis, mais elle n’existe pas sur SQL Server
- Supprimer une colonne avec DROP COLUMN est irréversible : sauvegardez vos données avant toute modification
- Les 5 exemples couvrent MySQL, PostgreSQL, SQL Server et SQLite pour couvrir 95 % des cas réels
Sommaire
- Syntaxe de base : ALTER TABLE ADD COLUMN
- Exemple 1 : ajouter une colonne avec une valeur par défaut
- Exemple 2 : ajouter plusieurs colonnes en une seule requête
- Exemple 3 : ajouter une colonne et la remplir avec des valeurs
- Exemple 4 : positionner la colonne après une colonne précise
- Exemple 5 : supprimer une colonne avec DROP COLUMN
- Comparatif des syntaxes par SGBD
- Les erreurs fréquentes et comment les éviter
- Bonnes pratiques pour modifier des tables en production
Quand j’ai commencé à enseigner le SQL à mes étudiants en BTS SIO, la question revenait systématiquement : « Comment on ajoute un champ à une table qui existe déjà ? ». La réponse tient en trois mots : ALTER TABLE ADD. Mais entre la syntaxe théorique et la réalité d’une base en production, il y a un monde. Types de données, valeurs par défaut, contraintes NOT NULL, différences entre MySQL et SQL Server : chaque détail compte pour éviter de casser une application.
Dans ce guide, je vous propose 5 exemples concrets pour maîtriser l’ajout de colonnes en SQL. Chaque exemple est testé, commenté et applicable immédiatement sur vos projets. Que vous utilisiez MySQL, PostgreSQL, SQL Server ou SQLite, vous trouverez la syntaxe exacte dont vous avez besoin. Si vous cherchez un rappel global sur le langage, mon SQL Cheat Sheet complet est un bon complément à garder sous la main.
Syntaxe de base : ALTER TABLE ADD COLUMN
Avant de plonger dans les exemples, posons les fondations. La commande ALTER TABLE est l’instruction DDL (Data Definition Language) qui permet de modifier la structure d’une table existante. Pour ajouter une colonne, la syntaxe générale est la suivante :
ALTER TABLE nom_table
ADD nom_colonne type_de_donnee [contraintes];
Sur certains SGBD comme PostgreSQL et SQLite, le mot-clé COLUMN est optionnel mais recommandé pour la lisibilité :
ALTER TABLE nom_table
ADD COLUMN nom_colonne type_de_donnee [contraintes];
Les deux formes sont acceptées. En revanche, sur SQL Server, on écrit directement ADD sans le mot COLUMN. Voici un premier exemple minimaliste qui ajoute une colonne email de type VARCHAR à une table clients :
ALTER TABLE clients
ADD email VARCHAR(255);
Cette instruction crée la colonne email à la fin de la table. Toutes les lignes existantes reçoivent la valeur NULL par défaut, sauf si vous spécifiez une valeur différente. C’est un point important : si votre colonne est définie comme NOT NULL sans valeur par défaut, la requête échouera sur la plupart des SGBD car les lignes existantes ne peuvent pas satisfaire la contrainte.
La documentation officielle MySQL sur ALTER TABLE détaille l’ensemble des options disponibles, et je vous recommande de la consulter si vous travaillez avec des tables partitionnées ou des index complexes.

Exemple 1 : ajouter une colonne avec une valeur par défaut
Dans la pratique, ajouter une colonne sans valeur par défaut pose un problème immédiat : toutes les lignes existantes contiennent NULL. Si votre application ne gère pas les NULL, vous risquez des erreurs côté PHP ou JavaScript. La solution est d’utiliser la clause DEFAULT.
-- MySQL / PostgreSQL
ALTER TABLE commandes
ADD COLUMN statut VARCHAR(20) DEFAULT 'en_attente' NOT NULL;
-- SQL Server
ALTER TABLE commandes
ADD statut VARCHAR(20) NOT NULL DEFAULT 'en_attente';
Avec cette syntaxe, chaque ligne existante dans la table commandes reçoit automatiquement la valeur ‘en_attente’ dans la colonne statut. La contrainte NOT NULL empêche toute insertion future sans valeur. C’est la combinaison que j’utilise systématiquement en cours et en production.
Quelques points à retenir :
- Sur PostgreSQL, la valeur par défaut est appliquée instantanément aux lignes existantes depuis la version 11 (avant, il fallait un UPDATE séparé)
- Sur MySQL, la valeur DEFAULT est écrite physiquement dans chaque ligne, ce qui peut prendre du temps sur des tables volumineuses
- Sur SQL Server, la clause DEFAULT crée implicitement une contrainte nommée automatiquement ; vous pouvez la nommer explicitement avec
CONSTRAINT df_statut DEFAULT 'en_attente'
Pour les colonnes numériques, la logique est identique :
ALTER TABLE produits
ADD COLUMN stock INT DEFAULT 0 NOT NULL;
Chaque produit existant démarre avec un stock à 0, et aucune insertion future ne peut ignorer ce champ. Si vous travaillez souvent avec des fonctions d’agrégation sur ces colonnes, mon article sur COUNT DISTINCT en SQL vous sera utile pour vos requêtes d’analyse.
Exemple 2 : ajouter plusieurs colonnes en une seule requête
Modifier une table une colonne à la fois fonctionne, mais quand vous devez en ajouter trois ou quatre, autant le faire en une seule instruction. Cela réduit le nombre de verrous sur la table et accélère l’opération, surtout sur les tables de plusieurs millions de lignes.
-- MySQL
ALTER TABLE employes
ADD COLUMN telephone VARCHAR(15),
ADD COLUMN date_embauche DATE,
ADD COLUMN salaire DECIMAL(10,2) DEFAULT 0.00;
-- SQL Server
ALTER TABLE employes
ADD telephone VARCHAR(15),
date_embauche DATE,
salaire DECIMAL(10,2) DEFAULT 0.00;
-- PostgreSQL
ALTER TABLE employes
ADD COLUMN telephone VARCHAR(15),
ADD COLUMN date_embauche DATE,
ADD COLUMN salaire DECIMAL(10,2) DEFAULT 0.00;
Notez la différence syntaxique : sur SQL Server, un seul ADD suffit et les colonnes sont séparées par des virgules. Sur MySQL et PostgreSQL, il faut répéter ADD COLUMN pour chaque colonne. C’est une source d’erreurs fréquente quand on passe d’un SGBD à l’autre.
En formation, je recommande toujours de scripter ces modifications dans un fichier de migration plutôt que de les exécuter directement dans un client SQL. Cela garantit la traçabilité et la reproductibilité de vos changements de schéma. Les frameworks comme Laravel (PHP), Django (Python) ou Sequelize (Node.js) gèrent nativement ce concept de migration.
Pour aller plus loin sur l’ordonnancement de vos résultats après modification de structure, consultez mon guide sur SQL ORDER BY avec plusieurs colonnes.
Exemple 3 : ajouter une colonne et la remplir avec des valeurs
Ajouter une colonne vide est rarement suffisant. Dans beaucoup de cas, vous devez immédiatement remplir cette colonne avec des valeurs calculées à partir de données existantes. La démarche se fait en deux étapes : d’abord l’ajout de la colonne, puis un UPDATE pour la peupler.
-- Étape 1 : ajouter la colonne
ALTER TABLE clients
ADD COLUMN nom_complet VARCHAR(200);
-- Étape 2 : remplir avec les données existantes
UPDATE clients
SET nom_complet = CONCAT(prenom, ' ', nom);
Sur SQL Server, la fonction CONCAT fonctionne de la même manière, mais vous pouvez aussi utiliser l’opérateur + :
ALTER TABLE clients
ADD nom_complet VARCHAR(200);
UPDATE clients
SET nom_complet = prenom + ' ' + nom;
Un cas fréquent en entreprise : ajouter une colonne calculée à partir d’une autre table. Par exemple, ajouter le nombre de commandes passées par chaque client :
ALTER TABLE clients
ADD COLUMN nb_commandes INT DEFAULT 0;
UPDATE clients c
SET nb_commandes = (
SELECT COUNT(*)
FROM commandes cmd
WHERE cmd.client_id = c.id
);

Cette approche en deux temps est la seule méthode fiable pour ajouter une colonne avec des valeurs calculées. Il n’existe pas de syntaxe ADD COLUMN ... AS (SELECT ...) en SQL standard. En revanche, SQL Server propose les colonnes calculées (computed columns) qui se recalculent automatiquement :
-- SQL Server uniquement
ALTER TABLE lignes_commande
ADD total_ligne AS (quantite * prix_unitaire);
Cette colonne total_ligne n’est pas stockée physiquement : elle est recalculée à chaque lecture. Pour la persister, ajoutez le mot-clé PERSISTED.
Exemple 4 : positionner la colonne après une colonne précise
Par défaut, toute nouvelle colonne est ajoutée à la fin de la table. En MySQL, vous pouvez contrôler la position avec les clauses AFTER ou FIRST. C’est purement cosmétique (l’ordre des colonnes n’affecte pas les performances), mais cela améliore la lisibilité quand vous consultez la table.
-- Ajouter après une colonne spécifique (MySQL uniquement)
ALTER TABLE clients
ADD COLUMN telephone VARCHAR(15) AFTER email;
-- Ajouter en première position (MySQL uniquement)
ALTER TABLE clients
ADD COLUMN code_client VARCHAR(10) FIRST;
Attention : cette fonctionnalité est spécifique à MySQL. Ni PostgreSQL, ni SQL Server, ni SQLite ne supportent les clauses AFTER ou FIRST. Si vous avez besoin de réorganiser les colonnes sur ces SGBD, la seule solution est de :
- Créer une nouvelle table avec l’ordre de colonnes souhaité
- Copier les données avec
INSERT INTO ... SELECT - Supprimer l’ancienne table
- Renommer la nouvelle table
-- PostgreSQL : réorganiser l'ordre des colonnes
CREATE TABLE clients_new (
id SERIAL PRIMARY KEY,
code_client VARCHAR(10),
nom VARCHAR(100),
email VARCHAR(255),
telephone VARCHAR(15)
);
INSERT INTO clients_new (id, nom, email)
SELECT id, nom, email FROM clients;
DROP TABLE clients;
ALTER TABLE clients_new RENAME TO clients;
En pratique, je déconseille cette manipulation en production. L’ordre des colonnes dans une table relationnelle n’a aucun impact sur les performances des requêtes. Concentrez-vous plutôt sur vos index et vos requêtes. Pour les rapports, l’instruction SELECT vous permet de choisir l’ordre d’affichage librement.
Exemple 5 : supprimer une colonne avec DROP COLUMN
Savoir ajouter une colonne implique aussi de savoir en supprimer une. La commande DROP COLUMN est l’inverse exact de ADD COLUMN, mais avec une différence majeure : elle est irréversible. Les données de la colonne supprimée sont définitivement perdues.
-- MySQL
ALTER TABLE clients
DROP COLUMN telephone;
-- PostgreSQL
ALTER TABLE clients
DROP COLUMN telephone;
-- SQL Server
ALTER TABLE clients
DROP COLUMN telephone;
La syntaxe est identique sur les trois SGBD majeurs. En revanche, il y a des pièges à connaître :
- Contraintes liées : si la colonne est référencée par une clé étrangère, un index ou une contrainte CHECK, vous devez d’abord supprimer cette dépendance
- SQL Server et DEFAULT : si la colonne possède une contrainte DEFAULT, il faut d’abord la supprimer avec
ALTER TABLE ... DROP CONSTRAINT - SQLite : la commande
DROP COLUMNn’est supportée que depuis la version 3.35.0 (mars 2021). Avant cette version, il faut recréer la table - Vues et procédures : toute vue ou procédure stockée qui référence la colonne supprimée provoquera une erreur à l’exécution
Pour supprimer plusieurs colonnes en une seule requête sur SQL Server :
ALTER TABLE clients
DROP COLUMN telephone, fax, commentaire;
Sur MySQL, il faut répéter DROP COLUMN :
ALTER TABLE clients
DROP COLUMN telephone,
DROP COLUMN fax,
DROP COLUMN commentaire;
Avant toute suppression, je recommande systématiquement de faire un SELECT sur la colonne concernée pour vérifier qu’elle ne contient pas de données exploitables, puis d’effectuer une sauvegarde complète de la table.
Comparatif des syntaxes par SGBD
Les différences syntaxiques entre SGBD sont une source constante de confusion. J’ai compilé dans ce tableau les principales variations pour vous éviter des allers-retours dans les documentations.
| Fonctionnalité | MySQL | PostgreSQL | SQL Server | SQLite |
|---|---|---|---|---|
| ADD COLUMN (syntaxe) | ADD COLUMN ou ADD | ADD COLUMN | ADD (sans COLUMN) | ADD COLUMN |
| Ajout multiple en un ADD | Non (répéter ADD COLUMN) | Non (répéter ADD COLUMN) | Oui (virgules) | Non |
| Clause AFTER / FIRST | Oui | Non | Non | Non |
| DEFAULT instantané | Réécriture physique | Instantané (v11+) | Instantané | Réécriture |
| DROP COLUMN | Oui | Oui | Oui | Oui (v3.35+) |
| Colonnes calculées | Generated columns (v5.7+) | Generated columns (v12+) | Computed columns | Non |
| RENAME COLUMN | Oui (v8.0+) | Oui | sp_rename | Oui (v3.25+) |
Ce tableau met en évidence un point essentiel : il n’existe pas de syntaxe universelle pour modifier la structure d’une table. Chaque SGBD a ses particularités. Si vous travaillez sur un projet multi-SGBD, utilisez un ORM ou un système de migration qui abstrait ces différences. La documentation PostgreSQL sur ALTER TABLE est particulièrement bien écrite et peut servir de référence pour comprendre la logique sous-jacente.

Les erreurs fréquentes et comment les éviter
Après des années à corriger les requêtes de mes étudiants (et parfois les miennes), voici les erreurs que je rencontre le plus souvent avec ALTER TABLE ADD.
Erreur 1 : NOT NULL sans DEFAULT sur une table non vide
-- Cette requête échoue si la table contient des données
ALTER TABLE clients
ADD COLUMN code_postal VARCHAR(5) NOT NULL;
-- Solution : ajouter un DEFAULT
ALTER TABLE clients
ADD COLUMN code_postal VARCHAR(5) NOT NULL DEFAULT '00000';
Le SGBD ne peut pas attribuer de valeur aux lignes existantes si vous imposez NOT NULL sans fournir de valeur par défaut. C’est logique, mais l’erreur est fréquente chez les débutants.
Erreur 2 : oublier les guillemets autour des valeurs DEFAULT textuelles
-- Erreur : valeur sans guillemets
ALTER TABLE clients
ADD COLUMN pays VARCHAR(50) DEFAULT France;
-- Correct
ALTER TABLE clients
ADD COLUMN pays VARCHAR(50) DEFAULT 'France';
Erreur 3 : utiliser AFTER sur PostgreSQL ou SQL Server
Comme nous l’avons vu, la clause AFTER est réservée à MySQL. Tenter de l’utiliser sur un autre SGBD génère une erreur de syntaxe immédiate.
Erreur 4 : ne pas vérifier si la colonne existe déjà
Si la colonne existe, la requête échoue. Pour les scripts de migration, utilisez une vérification conditionnelle :
-- MySQL
SET @col_exists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'clients' AND COLUMN_NAME = 'telephone');
SET @query = IF(@col_exists = 0,
'ALTER TABLE clients ADD COLUMN telephone VARCHAR(15)',
'SELECT 1');
PREPARE stmt FROM @query;
EXECUTE stmt;
-- PostgreSQL (plus simple)
ALTER TABLE clients
ADD COLUMN IF NOT EXISTS telephone VARCHAR(15);
PostgreSQL offre la syntaxe la plus élégante avec IF NOT EXISTS. Sur les autres SGBD, il faut interroger le schéma d’information. Pour des requêtes de comptage avancées sur vos tables, mon article sur COUNT unique en SQL vous donne les bonnes pratiques.
Erreur 5 : ne pas prendre en compte le verrouillage de table
Sur les grosses tables, un ALTER TABLE peut verrouiller la table pendant plusieurs minutes. MySQL 5.6+ supporte les modifications en ligne (online DDL) pour certaines opérations, mais pas toutes. Vérifiez toujours la compatibilité de votre version avec la liste des opérations DDL en ligne de MySQL.
Bonnes pratiques pour modifier des tables en production
Modifier la structure d’une table sur un serveur de développement est une chose. Le faire sur une base de production avec des utilisateurs connectés en est une autre. Voici mes recommandations issues de situations réelles.
1. Toujours sauvegarder avant de modifier
Même si ADD COLUMN est non destructif, l’habitude de sauvegarder avant toute modification DDL vous sauvera un jour. Un simple mysqldump ou pg_dump de la table concernée suffit :
-- MySQL
mysqldump -u root -p ma_base clients > clients_backup.sql
-- PostgreSQL
pg_dump -t clients ma_base > clients_backup.sql
2. Tester sur un environnement de staging
Reproduisez la modification sur une copie de la base avant de la jouer en production. Cela permet de mesurer le temps d’exécution et de détecter les éventuels verrous ou conflits de contraintes.
3. Exécuter les modifications en heures creuses
Pour les tables de plus de 1 million de lignes, planifiez vos ALTER TABLE pendant les plages de maintenance. Sur MySQL avec InnoDB, l’ajout d’une colonne avec DEFAULT nécessite une réécriture complète de la table, ce qui peut prendre plusieurs minutes.
4. Utiliser des outils de migration en ligne
Pour les bases très volumineuses, des outils comme pt-online-schema-change (Percona Toolkit) ou gh-ost (GitHub) permettent de modifier le schéma sans verrouiller la table. Ces outils créent une copie de la table, appliquent la modification, puis échangent les tables de manière atomique.
5. Documenter chaque changement de schéma
Maintenez un fichier de migration versionné dans votre dépôt Git. Chaque modification de schéma doit être traçable, réversible et accompagnée d’un script de rollback. Si vous travaillez avec SQL Server 2022, mon guide sur les nouveautés de SQL Server 2022 couvre les améliorations apportées à la gestion des schémas.
6. Attention aux arrondis dans les colonnes numériques
Quand vous ajoutez une colonne DECIMAL ou FLOAT, le choix de la précision a des conséquences directes sur vos calculs. Un DECIMAL(10,2) ne stocke que deux décimales. Pour comprendre les pièges des arrondis SQL, consultez mon article sur la fonction ROUND en SQL.
À retenir
- Utilisez toujours DEFAULT avec NOT NULL pour éviter les erreurs sur les lignes existantes
- Préférez l’ajout de plusieurs colonnes en une seule requête pour limiter les verrous sur la table
- Testez vos ALTER TABLE sur un environnement de staging avant la production, surtout au-delà de 1 million de lignes
- N’oubliez pas que la clause AFTER est exclusivement disponible sur MySQL
- Sauvegardez systématiquement avant tout DROP COLUMN : la suppression est irréversible
Questions fréquentes
Comment ajouter une colonne en SQL sans perdre les données existantes ?
La commande ALTER TABLE nom_table ADD COLUMN nom_colonne type; ajoute une colonne sans toucher aux données existantes. Les lignes déjà présentes reçoivent la valeur NULL (ou la valeur DEFAULT si vous en spécifiez une). Aucune donnée n’est supprimée ni modifiée.
Oui. Sur MySQL et PostgreSQL, répétez Peut-on ajouter plusieurs colonnes en même temps en SQL ?
ADD COLUMN séparé par des virgules. Sur SQL Server, un seul ADD suivi des colonnes séparées par des virgules suffit. Cette approche est plus performante car elle ne nécessite qu’un seul verrou sur la table.
Les deux formes sont équivalentes sur MySQL et PostgreSQL. Le mot-clé Quelle est la différence entre ADD et ADD COLUMN en SQL ?
COLUMN est optionnel et n’a aucun impact sur le résultat. Sur SQL Server, on utilise uniquement ADD sans COLUMN. Je recommande d’inclure COLUMN pour la lisibilité du code.
SQL Server ne supporte pas la clause Comment ajouter une colonne après une colonne spécifique en SQL Server ?
AFTER. La nouvelle colonne est toujours ajoutée en fin de table. Pour réorganiser l’ordre des colonnes, vous devez recréer la table avec l’ordre souhaité, copier les données, supprimer l’ancienne table et renommer la nouvelle. En pratique, l’ordre des colonnes n’affecte pas les performances.
Si la table contient des lignes, la requête échoue avec une erreur car le SGBD ne peut pas attribuer de valeur aux lignes existantes. La solution est d’ajouter une clause Que se passe-t-il si j’ajoute une colonne NOT NULL sans valeur par défaut ?
DEFAULT avec une valeur appropriée, ou d’ajouter la colonne sans NOT NULL, de remplir les valeurs avec un UPDATE, puis d’appliquer la contrainte.
Utilisez Comment supprimer une colonne en SQL ?
ALTER TABLE nom_table DROP COLUMN nom_colonne;. Cette opération est irréversible : toutes les données de la colonne sont définitivement supprimées. Sur SQLite, cette commande nécessite la version 3.35.0 minimum. Pensez à vérifier les dépendances (clés étrangères, vues, index) avant de supprimer.
Cela dépend du SGBD et de la version. PostgreSQL 11+ applique les valeurs DEFAULT de manière instantanée sans réécriture. MySQL avec InnoDB supporte certaines modifications en ligne (Online DDL). Pour les très grosses tables, des outils comme pt-online-schema-change ou gh-ost permettent d’éviter le verrouillage.L’ajout d’une colonne verrouille-t-il la table ?
Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.