Comment ALTER peut-il être utilisé pour supprimer une colonne dans une table MySQL si cette colonne existe?
Je sais que je peux utiliser ALTER TABLE my_table DROP COLUMN my_column
, mais cela jettera une erreur s'il my_column
n'existe pas. Existe-t-il une autre syntaxe pour supprimer la colonne de manière conditionnelle?
J'utilise MySQL version 4.0.18.
Réponses:
Pour MySQL, il n'y en a pas: MySQL Feature Request .
Autoriser cela est sans doute une très mauvaise idée, de toute façon:
IF EXISTS
indique que vous exécutez des opérations destructives sur une base de données avec (pour vous) une structure inconnue. Il peut y avoir des situations où cela est acceptable pour un travail local rapide et sale, mais si vous êtes tenté d'exécuter une telle déclaration contre des données de production (dans une migration, etc.), vous jouez avec le feu.Mais si vous insistez, il n'est pas difficile de simplement vérifier d'abord l'existence dans le client, ou d'attraper l'erreur.
MariaDB prend également en charge les éléments suivants à partir de 10.0.2:
DROP [COLUMN] [IF EXISTS] col_name
c'est à dire
ALTER TABLE my_table DROP IF EXISTS my_column;
Mais c'est sans doute une mauvaise idée de s'appuyer sur une fonctionnalité non standard supportée par une seule des nombreuses fourches de MySQL.
la source
Il n'y a pas de support de niveau de langue pour cela dans MySQL. Voici une solution de contournement impliquant les méta-données MySQL information_schema dans la version 5.0+, mais elle ne résoudra pas votre problème dans la version 4.0.18.
drop procedure if exists schema_change; delimiter ';;' create procedure schema_change() begin /* delete columns if they exist */ if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column1') then alter table table1 drop column `column1`; end if; if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column2') then alter table table1 drop column `column2`; end if; /* add columns */ alter table table1 add column `column1` varchar(255) NULL; alter table table1 add column `column2` varchar(255) NULL; end;; delimiter ';' call schema_change(); drop procedure if exists schema_change;
J'ai écrit des informations plus détaillées dans un article de blog .
la source
Je sais qu'il s'agit d'un ancien thread, mais il existe un moyen simple de gérer cette exigence sans utiliser de procédures stockées. Cela peut aider quelqu'un.
set @exist_Check := ( select count(*) from information_schema.columns where TABLE_NAME='YOUR_TABLE' and COLUMN_NAME='YOUR_COLUMN' and TABLE_SCHEMA=database() ) ; set @sqlstmt := if(@exist_Check>0,'alter table YOUR_TABLE drop column YOUR_COLUMN', 'select ''''') ; prepare stmt from @sqlstmt ; execute stmt ;
J'espère que cela aide quelqu'un, comme moi (après de nombreux essais et erreurs).
la source
Je viens de créer une procédure réutilisable qui peut aider à rendre
DROP COLUMN
idempotent:-- column_exists: DROP FUNCTION IF EXISTS column_exists; DELIMITER $$ CREATE FUNCTION column_exists( tname VARCHAR(64), cname VARCHAR(64) ) RETURNS BOOLEAN READS SQL DATA BEGIN RETURN 0 < (SELECT COUNT(*) FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = SCHEMA() AND `TABLE_NAME` = tname AND `COLUMN_NAME` = cname); END $$ DELIMITER ; -- drop_column_if_exists: DROP PROCEDURE IF EXISTS drop_column_if_exists; DELIMITER $$ CREATE PROCEDURE drop_column_if_exists( tname VARCHAR(64), cname VARCHAR(64) ) BEGIN IF column_exists(tname, cname) THEN SET @drop_column_if_exists = CONCAT('ALTER TABLE `', tname, '` DROP COLUMN `', cname, '`'); PREPARE drop_query FROM @drop_column_if_exists; EXECUTE drop_query; END IF; END $$ DELIMITER ;
Usage:
CALL drop_column_if_exists('my_table', 'my_column');
Exemple:
SELECT column_exists('my_table', 'my_column'); -- 1 CALL drop_column_if_exists('my_table', 'my_column'); -- success SELECT column_exists('my_table', 'my_column'); -- 0 CALL drop_column_if_exists('my_table', 'my_column'); -- success SELECT column_exists('my_table', 'my_column'); -- 0
la source
La réponse de Chase Seibert fonctionne, mais j'ajouterais que si vous avez plusieurs schémas, vous souhaitez modifier le SELECT ainsi:
select * from information_schema.columns where table_schema in (select schema()) and table_name=...
la source
La façon la plus simple de résoudre ce problème (qui fonctionnera) est peut-être:
CREATE new_table AS SELECT id, col1, col2, ... (seulement les colonnes que vous voulez réellement dans la table finale) FROM ma_table;
RENOMMER ma_table à ancienne_table, nouvelle_table à ma_table;
DROP old_table;
Ou conservez old_table pour une restauration si nécessaire.
Cela fonctionnera mais les clés étrangères ne seront pas déplacées. Vous devrez les rajouter plus tard à ma_table; également les clés étrangères dans d'autres tables qui référencent my_table devront être corrigées (pointées vers la nouvelle my_table).
Bonne chance...
la source
Vous pouvez utiliser ce script, utiliser votre colonne, votre schéma et le nom de votre table
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName' AND TABLE_SCHEMA = SchemaName) BEGIN ALTER TABLE TableName DROP COLUMN ColumnName; END;
la source
Je me rends compte que ce fil est assez vieux maintenant, mais j'avais le même problème. C'était ma solution très basique utilisant MySQL Workbench, mais cela a bien fonctionné ...
x
DROPa
;toutes les tables qui avaient la table n'ont maintenant aucune table qui n'a pas montré une erreur dans les journaux
alors vous pouvez trouver / remplacer 'drop
a
' changez-le en 'ADD COLUMNb
INT NULL' etc et relancez le tout ....un peu maladroit, mais enfin vous obtenez le résultat final et vous pouvez contrôler / surveiller l'ensemble du processus et n'oubliez pas de sauvegarder vos scripts SQL au cas où vous en auriez à nouveau besoin.
la source