如果MySQL中存在列,则使用ALTER删除列

时间:2008-10-06 10:29:16

标签: mysql ddl mysql4

如果该列存在,如何使用ALTER删除MySQL表中的列?

我知道我可以使用ALTER TABLE my_table DROP COLUMN my_column,但如果my_column不存在,则会引发错误。有条件地删除列的替代语法吗?

我正在使用MySQL 4.0.18版。

8 个答案:

答案 0 :(得分:51)

对于MySQL,没有: MySQL Feature Request

无论如何,允许这可能是一个非常糟糕的主意:IF EXISTS表示您正在使用(对您来说)未知结构的数据库上运行破坏性操作。在某些情况下,这对于快速和肮脏的本地工作来说是可以接受的,但是如果您想要针对生产数据(在迁移等中)运行这样的声明,那么您就是在玩火。

但是如果你坚持认为,在客户端首先检查存在性或捕获错误并不困难。

MariaDB还支持从10.0.2开始的以下内容:

  

DROP [COLUMN] [IF EXISTS] col_name

我。即

  

ALTER TABLE my_table DROP IF EXISTS my_column;

但依赖于MySQL的几个分支中只有一个支持的非标准功能,这可能是一个坏主意。

答案 1 :(得分:42)

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;

我在blog post中写了一些更详细的信息。

答案 2 :(得分:10)

我知道这是一个旧线程,但有一种简单的方法可以在不使用存储过程的情况下处理此要求。这可能有助于某人。

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 ;

希望这有助于某人,就像我一样(经过大量的试验和错误)。

答案 3 :(得分:10)

我刚刚建立了一个可重用的程序,可以帮助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

答案 4 :(得分:5)

Chase Seibert的答案有效,但我想补充一点,如果你有几个架构,你想要改变SELECT:

select * from information_schema.columns where table_schema in (select schema()) and table_name=...

答案 5 :(得分:1)

您可以使用此脚本,使用您的列,架构和表名

 IF EXISTS (`enter code here`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;

答案 6 :(得分:0)

也许解决此问题的最简单方法是:

  • 创建new_table AS SELECT id,col1,col2,...(仅最终表中实际需要的列) 从my_table;

  • 将my_table重命名为old_table,将new_table重命名为my_table;

  • DROP old_table;

或根据需要保留old_table进行回滚。

这将起作用,但是外键不会被移动。您稍后必须将它们重新添加到my_table;另外,引用my_table的其他表中的外键也必须固定(指向新的my_table)。

祝你好运...

答案 7 :(得分:-3)

我意识到这个线程现在很老了,但我遇到了同样的问题。 这是我使用MySQL Workbench的非常基本的解决方案,但它工作得很好......

  1. 获取一个新的sql编辑器并执行SHOW TABLES以获取表的列表
  2. 选择所有行,然后从上下文菜单中选择复制到剪贴板(未引用)
  3. 将名称列表粘贴到另一个编辑器标签
  4. 编写您的查询,即ALTER TABLE x DROP a;
  5. 进行一些复制和粘贴,因此最终会对每个表进行单独查询
  6. 切换发生错误时工作台是否应停止
  7. 点击执行并查看输出日志
  8. 任何拥有该表的表现在都没有 任何没有的表都会在日志中显示错误

    然后您可以找到/替换'drop a'将其更改为'ADD COLUMN b INT NULL'等并再次运行整个事物....

    有点笨重,但最后你得到了最终的结果,你可以控制/监控整个过程,并记得保存sql脚本以防你再次需要它们。