当前位置:  开发笔记 > 后端 > 正文

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

如何解决《如果MySQL中存在列,则使用ALTER删除列》经验,为你挑选了5个好方法。

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

我知道我可以使用ALTER TABLE my_table DROP COLUMN my_column,但如果my_column不存在则会抛出错误.有条件地删除列的替代语法是什么?

我使用的是MySQL 4.0.18版.



1> MattW...:

对于MySQL,没有: MySQL功能请求.

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

但是如果你坚持,那么首先在客户端检查存在或捕获错误并不困难.

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

DROP [COLUMN] [IF EXISTS] col_name

ALTER TABLE my_table DROP IF EXISTS my_column;

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


哇.在2005年提到 - 9年前.我猜这是优先考虑的事项......
"允许这可能是一个非常糟糕的主意," - 我不同意.为什么somone会对用户用例做出假设?我有一堆数据库,我需要让它们同步.当软件比人类更聪明时,它真的很烦人......
有没有办法在纯SQL中执行此操作?
MariaDB从10.0.2开始支持它
14年了,仍然不存在。我认为这不会完成。

2> Chase Seiber..:

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;

我在博文中写了一些更详细的信息.


我认为总结DrHyde作为评论的贡献是很重要的,因为当它回答它自己的时候并不明显.确保检查是否未修改其他数据库:SELECT*from information_schema.columns WHERE table_name ="country"AND column_name ="updated_at"AND table_schema = DATABASE()\ G

3> sp00m..:

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

我知道这是一个旧线程,但有一种简单的方法来处理这个要求而不使用存储过程.这可能对某人有帮助.

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 ;

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



5> DrHyde..:

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

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

推荐阅读
Chloemw
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有