繁体   English   中英

使用 ALTER 删除 MySQL 中存在的列

[英]Using ALTER to drop a column if it exists in MySQL

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

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

我使用的是 MySQL 4.0.18 版。

对于 MySQL,没有: MySQL Feature Request

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

但是,如果您坚持,那么简单地首先在客户端中检查是否存在或捕获错误并不困难。

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

DROP [COLUMN] [IF EXISTS] col_name 

IE

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;

我在博客文章中写了一些更详细的信息。

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

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 ;

希望这对某人有帮助,就像对我一样(经过多次反复试验)。

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

Chase Seibert 的答案有效,但我要补充一点,如果您有多个架构,您想这样更改 SELECT:

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

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

 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;

也许解决这个问题的最简单方法(可行)是:

  • CREATE new_table AS SELECT id, col1, col2, ...(只有最终表中你真正想要的列) FROM my_table;

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

  • 删除旧表;

或者在需要时保留 old_table 以进行回滚。

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

祝你好运...

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

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

任何有该表的表现在都没有任何没有的表将在日志中显示错误

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM