在ALTER TABLE - mysql之前检查列是否存在

时间:2011-11-21 22:56:00

标签: mysql alter-table

有没有办法在ALTER TABLE ADD coumn_name语句运行之前检查某个列是否存在于mySQL数据库中?排序IF column DOES NOT EXIST ALTER TABLE

我已经尝试了ALTER IGNORE TABLE my_table ADD my_column但如果我添加的列已经存在,这仍会引发错误。

编辑:用例是升级已安装的Web应用程序中的表 - 为了简单起见,我想确保我需要的列存在,如果不存在,请使用{{1}添加它们}}

10 个答案:

答案 0 :(得分:9)

由于mysql控制语句(例如“IF”)仅适用于存储过程,因此可以创建并执行临时语句:

DROP PROCEDURE IF EXISTS add_version_to_actor;

DELIMITER $$

CREATE DEFINER=CURRENT_USER PROCEDURE add_version_to_actor ( ) 
BEGIN
DECLARE colName TEXT;
SELECT column_name INTO colName
FROM information_schema.columns 
WHERE table_schema = 'connjur'
    AND table_name = 'actor'
AND column_name = 'version';

IF colName is null THEN 
    ALTER TABLE  actor ADD  version TINYINT NOT NULL DEFAULT  '1' COMMENT  'code version of actor when stored';
END IF; 
END$$

DELIMITER ;

CALL add_version_to_actor;

DROP PROCEDURE add_version_to_actor;

答案 1 :(得分:8)

你认为你可以尝试这个吗?:

SELECT IFNULL(column_name, '') INTO @colName
FROM information_schema.columns 
WHERE table_name = 'my_table'
AND column_name = 'my_column';

IF @colName = '' THEN 
    -- ALTER COMMAND GOES HERE --
END IF;

这不是单行,但你至少可以看看它是否适合你?至少在等待更好的解决方案时......

答案 2 :(得分:6)

实用程序功能和程序

首先,我有一组实用程序函数和过程,用于执行诸如删除外键,普通键和列之类的操作。我只是将它们留在数据库中,以便我可以根据需要使用它们。

他们在这里。

delimiter $$

create function column_exists(ptable text, pcolumn text)
  returns bool
  reads sql data
begin
  declare result bool;
  select
    count(*)
  into
    result
  from
    information_schema.columns
  where
    `table_schema` = 'my_database' and
    `table_name` = ptable and
    `column_name` = pcolumn;
  return result;
end $$

create function constraint_exists(ptable text, pconstraint text)
  returns bool
  reads sql data
begin
  declare result bool;
  select
    count(*)
  into
    result
  from
    information_schema.table_constraints
  where
    `constraint_schema` = 'my_database' and
    `table_schema` = 'my_database' and
    `table_name` = ptable and
    `constraint_name` = pconstraint;
  return result;
end $$

create procedure drop_fk_if_exists(ptable text, pconstraint text)
begin
  if constraint_exists(ptable, pconstraint) then
    set @stat = concat('alter table ', ptable, ' drop foreign key ', pconstraint);
    prepare pstat from @stat;
    execute pstat;
  end if;
end $$

create procedure drop_key_if_exists(ptable text, pconstraint text)
begin
  if constraint_exists(ptable, pconstraint) then
    set @stat = concat('alter table ', ptable, ' drop key ', pconstraint);
    prepare pstat from @stat;
    execute pstat;
  end if;
end $$

create procedure drop_column_if_exists(ptable text, pcolumn text)
begin
  if column_exists(ptable, pcolumn) then
    set @stat = concat('alter table ', ptable, ' drop column ', pcolumn);
    prepare pstat from @stat;
    execute pstat;
  end if;
end $$

delimiter ;

使用上面的实用程序删除约束和列

有了这些,就可以很容易地使用它们来检查存在的列和约束:

-- Drop service.component_id
call drop_fk_if_exists('service', 'fk_service_1');
call drop_key_if_exists('service', 'component_id');
call drop_column_if_exists('service', 'component_id');

-- Drop commit.component_id
call drop_fk_if_exists('commit', 'commit_ibfk_1');
call drop_key_if_exists('commit', 'commit_idx1');
call drop_column_if_exists('commit', 'component_id');

-- Drop component.application_id
call drop_fk_if_exists('component', 'fk_component_1');
call drop_key_if_exists('component', 'application_id');
call drop_column_if_exists('component', 'application_id');

答案 3 :(得分:4)

使用John Watson的下面的例子制作一个计数句子。

 SELECT count(*) FROM information_schema.COLUMNS
     WHERE COLUMN_NAME = '...'
     and TABLE_NAME = '...'
     and TABLE_SCHEMA = '...'

将结果保存为整数,然后将其作为应用ADD COLUMN句子的条件。

答案 4 :(得分:1)

虽然这是一个相当古老的帖子,但我仍然对分享我对这个问题的解决方案感到满意。如果列不存在,那么肯定会发生异常,然后我在表中创建列。

我刚刚使用了以下代码:

 try
   {
         DATABASE_QUERY="SELECT gender from USER;";
         db.rawQuery(DATABASE_QUERY, null);
   }
   catch (Exception e)
   {
    e.printStackTrace();

        DATABASE_UPGRADE="alter table USER ADD COLUMN gender VARCHAR(10) DEFAULT 0;";
                db.execSQL(DATABASE_UPGRADE);
   } 

答案 5 :(得分:0)

如果列存在,您可以使用CONTINUE处理程序创建一个过程(请注意此代码在PHPMyAdmin中不起作用):

DROP PROCEDURE IF EXISTS foo;
CREATE PROCEDURE foo() BEGIN
    DECLARE CONTINUE HANDLER FOR 1060 BEGIN END;
    ALTER TABLE `tableName` ADD `columnName` int(10) NULL AFTER `otherColumn`;
END;
CALL foo();
DROP PROCEDURE foo;

如果列已存在,则此代码不应引发任何错误。它将不执行任何操作并继续执行SQL的其余部分。

答案 6 :(得分:0)

DELIMITER $$

DROP PROCEDURE IF EXISTS `addcol` $$
CREATE DEFINER=`admin`@`localhost` PROCEDURE `addcol`(tbn varchar(45), cn varchar(45), ct varchar(45))
BEGIN
#tbn: table name, cn: column name, ct: column type
DECLARE CONTINUE HANDLER FOR 1060 BEGIN END;
set cn = REPLACE(cn, ' ','_');
set @a = '';
set @a = CONCAT("ALTER TABLE `", tbn ,"` ADD column `", cn ,"` ", ct);
PREPARE stmt FROM @a;
EXECUTE stmt;

END $$

DELIMITER ;

答案 7 :(得分:0)

此语法对我有用:

SHOW COLUMNS FROM <表名>类似于''

此帖子中的更多内容: https://mzulkamal.com/blog/mysql-5-7-check-if-column-exist?viewmode=0

答案 8 :(得分:-1)

您可以测试列是否存在:

IF EXISTS (
     SELECT * FROM information_schema.COLUMNS
     WHERE COLUMN_NAME = '...'
     and TABLE_NAME = '...'
     and TABLE_SCHEMA = '...')

...

只需填写您的列名,表名和数据库名称。

答案 9 :(得分:-3)

根据MYSQL社区:

IGNORE是标准SQL的MySQL扩展。如果新表中的唯一键上存在重复项,或者启用了严格模式时出现警告,它将控制ALTER TABLE的工作方式。如果未指定IGNORE,则复制将中止并在发生重复键错误时回滚。如果指定了IGNORE,则只对一行使用唯一键上具有重复项的行。其他冲突的行将被删除。不正确的值将被截断为最接近的匹配可接受值。

所以一个有效的代码是:     ALTER IGNORE TABLE CLIENTS ADD CLIENT_NOTES TEXT DEFAULT NULL;

此处发布的数据: http://dev.mysql.com/doc/refman/5.1/en/alter-table.html