如果列不存在,则将列添加到 mysql 表中
我的研究和实验还没有得出答案,所以我希望得到一些帮助。
我正在修改一个应用程序的安装文件,该文件在以前的版本中没有我现在要添加的列。 我不想手动添加列,而是在安装文件中添加,并且仅当新列不存在于表中时才添加。
该表的创建方式如下:
CREATE TABLE IF NOT EXISTS `#__comm_subscribers` (
`subscriber_id` int(11) NOT NULL auto_increment,
`user_id` int(11) NOT NULL default '0',
`subscriber_name` varchar(64) NOT NULL default '',
`subscriber_surname` varchar(64) NOT NULL default '',
`subscriber_email` varchar(64) NOT NULL default '',
`confirmed` tinyint(1) NOT NULL default '0',
`subscribe_date` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`subscriber_id`),
UNIQUE KEY `subscriber_email` (`subscriber_email`)
) ENGINE=MyISAM CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' COMMENT='Subscribers for Comm are stored here.';
如果我在创建表语句下方添加以下内容,那么我不确定如果该列已经存在(并且可能已填充)会发生什么:
ALTER TABLE `#__comm_subscribers` ADD `subscriber_surname`;
ALTER TABLE `#__comm_subscribers` MODIFY `subscriber_surname` varchar(64) NOT NULL default '';
因此,我尝试了在某处找到的以下内容。 这似乎不起作用,但我不完全确定我正确使用了它。
/*delimiter '//'
CREATE PROCEDURE addcol() BEGIN
IF NOT EXISTS(
SELECT * FROM information_schema.COLUMNS
WHERE COLUMN_NAME='subscriber_surname' AND TABLE_NAME='#__comm_subscribers'
)
THEN
ALTER TABLE `#__comm_subscribers`
ADD COLUMN `subscriber_surname` varchar(64) NOT NULL default '';
END IF;
END;
//
delimiter ';'
CALL addcol();
DROP PROCEDURE addcol;*/
有没有人有一个好方法来做到这一点?
My research and experiments haven't yielded an answer yet, so I am hoping for some help.
I am modifying the install file of an application which in previous versions did not have a column which I want to add now. I do not want to add the column manually, but in the installation file and only if the new column does not already exist in the table.
The table is created as follows:
CREATE TABLE IF NOT EXISTS `#__comm_subscribers` (
`subscriber_id` int(11) NOT NULL auto_increment,
`user_id` int(11) NOT NULL default '0',
`subscriber_name` varchar(64) NOT NULL default '',
`subscriber_surname` varchar(64) NOT NULL default '',
`subscriber_email` varchar(64) NOT NULL default '',
`confirmed` tinyint(1) NOT NULL default '0',
`subscribe_date` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`subscriber_id`),
UNIQUE KEY `subscriber_email` (`subscriber_email`)
) ENGINE=MyISAM CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' COMMENT='Subscribers for Comm are stored here.';
If I add the following, below the create table statement, then I am not sure what happens if the column already exists (and perhaps is populated):
ALTER TABLE `#__comm_subscribers` ADD `subscriber_surname`;
ALTER TABLE `#__comm_subscribers` MODIFY `subscriber_surname` varchar(64) NOT NULL default '';
So, I tried the following which I found somewhere. This does not seem to work but I am not entirely sure I used it properly.
/*delimiter '//'
CREATE PROCEDURE addcol() BEGIN
IF NOT EXISTS(
SELECT * FROM information_schema.COLUMNS
WHERE COLUMN_NAME='subscriber_surname' AND TABLE_NAME='#__comm_subscribers'
)
THEN
ALTER TABLE `#__comm_subscribers`
ADD COLUMN `subscriber_surname` varchar(64) NOT NULL default '';
END IF;
END;
//
delimiter ';'
CALL addcol();
DROP PROCEDURE addcol;*/
Does anyone have a good way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
这是一个可行的解决方案(刚刚在 Solaris 上使用 MySQL 5.0 进行了尝试):
乍一看,它可能看起来比应有的更复杂,但我们必须在这里处理以下问题:
IF
语句仅有效在存储过程中,而不是直接运行时,例如,在 mysql 客户端中,
SHOW COLUMNS
在存储过程中不起作用,因此必须使用 INFORMATION_SCHEMA重新定义分隔符以便能够创建存储过程。 不要
忘记将分隔符切换回来!
对
TABLE_SCHEMA=DATABASE()
进行过滤。DATABASE()
返回名称当前选择的数据库。
Here is a working solution (just tried out with MySQL 5.0 on Solaris):
On a first glance it probably looks more complicated than it should, but we have to deal with following problems here:
IF
statements only work in stored procedures, not when run directly,e.g. in mysql client
SHOW COLUMNS
does not work in stored procedure so have to use INFORMATION_SCHEMAredefine the delimiter to be able to create stored procedures. Do not
forget to switch the delimiter back!
filter on
TABLE_SCHEMA=DATABASE()
.DATABASE()
returns the name ofthe currently selected database.
如果您使用 MariaDB,则无需使用存储过程。 只需使用,例如:
参见此处
If you are on MariaDB, no need to use stored procedures. Just use, for example:
See here
请注意,5.0 之前的 MySQL 不支持
INFORMATION_SCHEMA
。 5.0之前也不支持存储过程,所以如果你需要支持MySQL 4.1,这个解决方案并不好。使用数据库迁移的框架使用的一种解决方案是在数据库中记录架构的修订号。 只是一个单列单行的表格,其中有一个整数指示当前有效的修订版本。 更新架构时,增加数字。
另一种解决方案是尝试
ALTER TABLE ADD COLUMN
命令。 如果该列已经存在,它应该抛出错误。捕获错误并在升级脚本中忽略它。
Note that
INFORMATION_SCHEMA
isn't supported in MySQL prior to 5.0. Nor are stored procedures supported prior to 5.0, so if you need to support MySQL 4.1, this solution isn't good.One solution used by frameworks that use database migrations is to record in your database a revision number for the schema. Just a table with a single column and single row, with an integer indicating which revision is current in effect. When you update the schema, increment the number.
Another solution would be to just try the
ALTER TABLE ADD COLUMN
command. It should throw an error if the column already exists.Catch the error and disregard it in your upgrade script.
大多数答案都涉及如何在存储过程中安全地添加列,我需要在不使用存储过程的情况下安全地向表添加列,并发现 MySQL 不允许使用 IF Exists() SP 之外。 我将发布我的解决方案,它可能会帮助处于相同情况的人。
Most of the answers address how to add a column safely in a stored procedure, I had the need to add a column to a table safely without using a stored proc and discovered that MySQL does not allow the use of
IF Exists()
outside a SP. I'll post my solution that it might help someone in the same situation.另一种方法是使用
declare continue handler
忽略错误:我认为这种方式比使用
exists
子查询更简洁。 特别是如果您有很多列要添加,并且您想要多次运行脚本。有关继续处理程序的更多信息可以在 http://dev 找到。 mysql.com/doc/refman/5.0/en/declare-handler.html
Another way to do this would be to ignore the error with a
declare continue handler
:I think its neater this way than with an
exists
subquery. Especially if you have a lot of columns to add, and you want to run the script several times.more info on continue handlers can be found at http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html
我正在使用 MySQL 5.5.19。
我喜欢拥有可以运行和重新运行而不会出现错误的脚本,尤其是在警告似乎持续存在的情况下,当我运行没有错误/警告的脚本时,稍后会再次出现。 就添加字段而言,我自己编写了一个过程以减少打字量:
创建 addFieldIfNotExists 过程的代码如下:
我没有编写一个过程来安全地修改列,但我认为可以很容易地修改上述过程来做到这一点。
I'm using MySQL 5.5.19.
I like having scripts that you can run and rerun without error, especially where warnings seem to linger, showing up again later while I'm running scripts that have no errors/warnings. As far as adding fields goes, I wrote myself a procedure to make it a little less typing:
The code to create the addFieldIfNotExists procedure is as follows:
I didn't write a procedure to safely modify a column, but I think the above procedure could be easily modified to do so.
我采用了 OP 的存储过程,并使其可重用且独立于模式。 显然它仍然需要MySQL 5。
I've taken the OP's sproc and made it reusable and schema independent. Obviously it still requires MySQL 5.
刚刚尝试了存储过程脚本。 问题似乎是分隔符周围的
'
标记。 MySQL Docs 显示不需要分隔符单引号。所以你想要:
而不是:
对我有用:)
Just tried the stored procedure script. Seems the problem is the
'
marks around the delimiters. The MySQL Docs show that delimiter characters do not need the single quotes.So you want:
Instead of:
Works for me :)
如果您在脚本中运行此命令,则需要在之后添加以下行以使其可重新运行,否则您会收到过程已存在错误。
If you are running this in a script, you'll want to add the following line afterwards to make it rerunnable, otherwise you get a procedure already exists error.
在 PHP 中添加列的最佳方法> PDO :
注意:表中的列不可重复,这意味着我们不需要检查列是否存在,但为了解决问题,我们检查上面的代码:
例如,如果它有效,则警报 1,如果不是 0 ,这意味着该列存在! :)
The best way for add the column in PHP > PDO :
Note: the column in the table is not repeatable, that means we don't need to check the existance of a column, but for solving the problem we check the above code:
for example if it works alert 1,if not 0, which means the column exist ! :)
检查 PDO 中是否存在列(100%)
Check if Column Exist or not in PDO (100%)
Jake https://stackoverflow.com/a/6476091/6751901 的过程是添加新列的非常简单且良好的解决方案,但多了一行:
您可以稍后在其中添加新列,下次也可以使用:
Procedure from Jake https://stackoverflow.com/a/6476091/6751901 is very simple and good solution for adding new columns, but with one additional line:
you can add new columns later there, and it will work next time too:
然后在 $res by Cycle 中查找您的列的键
像这样:
Then in $res by cycle look for key of your column
Smth like this:
下面是 MySQL 中的存储过程,如果数据库中不存在列,则在不同数据库的不同表中添加列,具有以下优点:
Below are the Stored procedure in MySQL To Add Column(s) in different Table(s) in different Database(s) if column does not exists in a Database(s) Table(s) with following advantages
这是我的 PHP/PDO 解决方案:
Here is my PHP/PDO solution to do that :