繁体   English   中英

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

[英]check if column exists before ALTER TABLE — mysql

有没有办法检查在运行ALTER TABLE ADD coumn_name语句之前(或作为) ALTER TABLE ADD coumn_name DB中是否存在列? IF column DOES NOT EXIST ALTER TABLE排序IF column DOES NOT EXIST ALTER TABLE事物。

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

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

由于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;

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

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;

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

实用功能和程序

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

他们来了。

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');

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

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

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

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

我刚刚使用下面的代码:

 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);
   } 

如果列存在,您可以使用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的其余部分。

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 ;

这个语法对我有用:

从<tablename> LIKE'<columnName>'显示列

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

您可以测试列是否存在:

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

...

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

根据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

暂无
暂无

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

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