如果该列存在,如何使用ALTER删除MySQL表中的列?
我知道我可以使用ALTER TABLE my_table DROP COLUMN my_column
,但如果my_column
不存在则会抛出错误.有条件地删除列的替代语法是什么?
我使用的是MySQL 4.0.18版.
对于MySQL,没有: MySQL功能请求.
无论如何,允许这可能是一个非常糟糕的主意:IF EXISTS
表示您正在使用(对您来说)未知结构的数据库上运行破坏性操作.在某些情况下,这对于快速和肮脏的本地工作来说是可以接受的,但是如果您想要针对生产数据(在迁移等中)运行这样的声明,那么您就会玩火.
但是如果你坚持,那么首先在客户端检查存在或捕获错误并不困难.
MariaDB还支持从10.0.2开始的以下内容:
DROP [COLUMN] [IF EXISTS] col_name
即
ALTER TABLE my_table DROP IF EXISTS my_column;
但依赖于MySQL的几个分支中只有一个支持的非标准功能,这可能是一个坏主意.
MySQL中没有语言级支持.这是一个涉及5.0+中的MySQL information_schema元数据的解决方法,但它不会解决您在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;
我在博文中写了一些更详细的信息.
我刚刚建立了一个可重用的程序,可以帮助制作DROP COLUMN
幂等法:
-- 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 ;
用法:
CALL drop_column_if_exists('my_table', 'my_column');
例:
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
我知道这是一个旧线程,但有一种简单的方法来处理这个要求而不使用存储过程.这可能对某人有帮助.
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 ;
希望这有助于某人,就像它一样(经过大量的试验和错误).
Chase Seibert的答案有效,但我想补充一点,如果你有几个架构,你想要改变SELECT:
select * from information_schema.columns where table_schema in (select schema()) and table_name=...