Blog développeur

« Etudie, non pour savoir plus, mais pour savoir mieux. »

SQL

Script d'ajout d'un champ dans une table

Par Guillaume Sarramegna, le 7 déc. 2015

La principale bonne pratique lors de la rédaction d'un script SQL d'installation ou de mise à jour d'une base de données est que celui-ci soit réexécutable à l'infini sans corrompre la base de données.

Parmi les erreurs à éviter il y a :

  • Ajout de lignes à chaque exécution d'un script avec des INSERT
  • Erreur lorsque qu'une table ou une procédure stockée doit être créée et qu'elle existe déjà
  • Et j'en passe...

Aujourd'hui je souhaitais donc partager une petite astuce lorsque vous avez besoin de modifier la structure d'une table en y ajoutant un champ supplémentaire. Si vous tenter d'éxécuter plusieurs fois le script suivant, vous aurez à partir de la seconde fois une belle erreur SQL.

ALTER TABLE `matable` ADD `monchamp` INT(0) NOT NULL ;

L'astuce est de créer une procédure stockée à la volée qui va se charger de vérifier si le champ n'existe pas et, le cas échéant, de le créer. Voici la formule magique.

-- On supprime la procédure stockée si elle existe déjà, afin d'éviter les erreurs et l'obsolescence de celle-ci
DROP PROCEDURE IF EXISTS AddColumnIfNotExists;
DELIMITER $$

CREATE PROCEDURE AddColumnIfNotExists(IN dbName tinytext, IN tableName tinytext, IN fieldName tinytext, IN fieldDef text)
BEGIN
	-- On vérifie si le champ existe déjà pour la base de données et la table données
	IF NOT EXISTS (
		SELECT * 
		FROM INFORMATION_SCHEMA.COLUMNS
		WHERE column_name = fieldName
		AND table_name = tableName
		AND table_schema = dbName
	)
	THEN
		-- On ajoute le champ s'il n'existe pas déjà
		SET @ddl = CONCAT('ALTER TABLE `', dbName, '`.`', tableName, '` ADD `', fieldName, '` ', fieldDef, ';');
		PREPARE stmt FROM @ddl;
		EXECUTE stmt;
	END IF;
END $$

DELIMITER ;

-- On appelle la procédure stockée pour ajouter le champ à la table si nécessaire (Database() renvoie le nom de la base de données en cours)
CALL AddColumnIfNotExists(Database(), 'matable', 'monchamp', 'INT(0) NOT NULL');

-- On supprime la procédure stockée pour éviter qu'elle n'encombre la base de données pour rien
DROP PROCEDURE AddColumnIfNotExists;

Voilà, c'est aussi simple que ça.

0 commentaire

Votre commentaire