[英]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.