有没有办法在ALTER TABLE ADD coumn_name
语句运行之前检查某个列是否存在于mySQL数据库中?排序IF column DOES NOT EXIST ALTER TABLE
。
我已经尝试了ALTER IGNORE TABLE my_table ADD my_column
但如果我添加的列已经存在,这仍会引发错误。
编辑:用例是升级已安装的Web应用程序中的表 - 为了简单起见,我想确保我需要的列存在,如果不存在,请使用{{1}添加它们}}
答案 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