为什么在DEFAULT子句中只能有一个CURRENT_TIMESTAMP的TIMESTAMP列?

为什么在DEFAULT或ON UPDATE子句中只能有一个CURRENT_TIMESTAMP的TIMESTAMP列?

CREATE TABLE `foo` ( `ProductID` INT(10) UNSIGNED NOT NULL, `AddedDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `UpdatedDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=INNODB; 

结果的错误:

错误代码:1293

表格定义不正确; 在DEFAULT或ON UPDATE子句中只能有一个TIMESTAMP列和CURRENT_TIMESTAMP

这个限制只是由于历史原因,代码遗留原因,在最近版本的MySQL中已经被取消:

MySQL 5.6.5的变化(2012-04-10,里程碑8)

以前,每个表最多有一个TIMESTAMP列可以自动初始化或更新为当前的date和时间。 这个限制已经解除了。 任何TIMESTAMP列定义都可以具有DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP子句的任意组合。 另外,这些子句现在可以和DATETIME列定义一起使用。 有关更多信息,请参阅自动初始化和更新TIMESTAMP和DATETIME。

http://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-5.html

我也想了很久以前。 我在我的历史中search了一下,我认为这个post是: http : //lists.mysql.com/internals/34919代表MySQL的半官方位置(在Oracle介入之前))

简而言之:

这个限制仅仅来自服务器当前实现这个特性的方式,并且没有其他原因存在。

所以他们的解释是“因为它是这样实现的”。 听起来不太科学。 我想这一切都来自一些旧的代码。 这是在上面的线程中build议的:“从第一个时间戳字段被自动设置/更新时的遗留”。

干杯!

我们可以给出时间戳的默认值来避免这个问题。

这篇文章给出了详细的解决方法: http : //gusiev.com/2009/04/update-and-create-timestamps-with-mysql/

 create table test_table( id integer not null auto_increment primary key, stamp_created timestamp default '0000-00-00 00:00:00', stamp_updated timestamp default now() on update now() ); 

请注意,在“插入”期间,有必要在两列中input空值:

 mysql> insert into test_table(stamp_created, stamp_updated) values(null, null); Query OK, 1 row affected (0.06 sec) mysql> select * from t5; +----+---------------------+---------------------+ | id | stamp_created | stamp_updated | +----+---------------------+---------------------+ | 2 | 2009-04-30 09:44:35 | 2009-04-30 09:44:35 | +----+---------------------+---------------------+ 2 rows in set (0.00 sec) mysql> update test_table set id = 3 where id = 2; Query OK, 1 row affected (0.05 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> select * from test_table; +----+---------------------+---------------------+ | id | stamp_created | stamp_updated | +----+---------------------+---------------------+ | 3 | 2009-04-30 09:44:35 | 2009-04-30 09:46:59 | +----+---------------------+---------------------+ 2 rows in set (0.00 sec) 

确实是一个执行错误。

MySQL中的本地方法是自己更新一个创builddate(如果你需要的话),让MySQL担心时间戳 update date ? update date : creation date update date ? update date : creation date如此:

 CREATE TABLE tracked_data( `data` TEXT, `timestamp` TIMESTAMP, `creation_date` TIMESTAMP ) ENGINE=INNODB; 

创build时插入NULL:

 INSERT INTO tracked_data(`data`,`creation_date`) VALUES ('creation..',NULL); 

时间戳的NULL值默认为CURRENT_TIMESTAMP。

在MySQL中,表的第一个TIMESTAMP列同时得到DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP属性,如果没有给出属性的话。 这就是为什么具有属性的TIMESTAMP列必须先出现,否则你会得到这个线程中描述的错误。

  1. 将列的数据types更改为datetime
  2. 设置触发器

如:

 DROP TRIGGER IF EXISTS `update_tablename_trigger`; DELIMITER // CREATE TRIGGER `update_tablename_trigger` BEFORE UPDATE ON `tablename` FOR EACH ROW SET NEW.`column_name` = NOW() // DELIMITER ; 

那么一个修复你可能是把它放在UpdatedDate字段上,并有一个触发器,只有当AddedDate为null时,才用UpdatedDate值更新AddedDate字段。

结合各种答案:

在MySQL 5.5中, DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP不能在DATETIME上添加,而只能在TIMESTAMP

规则:

1)每个表最多有一个TIMESTAMP列可以自动(或手动[ My addition ])初始化或更新为当前的date和时间。 (MySQL文档)。

因此,只有一个TIMESTAMP可以在DEFAULTON UPDATE子句中具有CURRENT_TIMESTAMP

2)第一个NOT NULL TIMESTAMP列没有一个明确的DEFAULT值,比如created_date timestamp default '0000-00-00 00:00:00'将被隐式地赋予一个DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ,因此后续的TIMESTAMP列不能被赋予CURRENT_TIMESTAMPDEFAULTON UPDATE子句

 CREATE TABLE `address` ( `id` int(9) NOT NULL AUTO_INCREMENT, `village` int(11) DEFAULT NULL, `created_date` timestamp default '0000-00-00 00:00:00', -- Since explicit DEFAULT value that is not CURRENT_TIMESTAMP is assigned for a NOT NULL column, -- implicit DEFAULT CURRENT_TIMESTAMP is avoided. -- So it allows us to set ON UPDATE CURRENT_TIMESTAMP on 'updated_date' column. -- How does setting DEFAULT to '0000-00-00 00:00:00' instead of CURRENT_TIMESTAMP help? -- It is just a temporary value. -- On INSERT of explicit NULL into the column inserts current timestamp. -- `created_date` timestamp not null default '0000-00-00 00:00:00', // same as above -- `created_date` timestamp null default '0000-00-00 00:00:00', -- inserting 'null' explicitly in INSERT statement inserts null (Ignoring the column inserts the default value)! -- Remember we need current timestamp on insert of 'null'. So this won't work. -- `created_date` timestamp null , // always inserts null. Equally useless as above. -- `created_date` timestamp default 0, // alternative to '0000-00-00 00:00:00' -- `created_date` timestamp, -- first 'not null' timestamp column without 'default' value. -- So implicitly adds DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP. -- Hence cannot add 'ON UPDATE CURRENT_TIMESTAMP' on 'updated_date' column. `updated_date` timestamp null on update current_timestamp, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=132 DEFAULT CHARSET=utf8; 

 INSERT INTO address (village,created_date) VALUES (100,null); 

 mysql> select * from address; +-----+---------+---------------------+--------------+ | id | village | created_date | updated_date | +-----+---------+---------------------+--------------+ | 132 | 100 | 2017-02-18 04:04:00 | NULL | +-----+---------+---------------------+--------------+ 1 row in set (0.00 sec) 

 UPDATE address SET village=101 WHERE village=100; 

 mysql> select * from address; +-----+---------+---------------------+---------------------+ | id | village | created_date | updated_date | +-----+---------+---------------------+---------------------+ | 132 | 101 | 2017-02-18 04:04:00 | 2017-02-18 04:06:14 | +-----+---------+---------------------+---------------------+ 1 row in set (0.00 sec) 

其他选项(但updated_date是第一列):

 CREATE TABLE `address` ( `id` int(9) NOT NULL AUTO_INCREMENT, `village` int(11) DEFAULT NULL, `updated_date` timestamp null on update current_timestamp, `created_date` timestamp not null , -- implicit default is '0000-00-00 00:00:00' from 2nd timestamp onwards -- `created_date` timestamp not null default '0000-00-00 00:00:00' -- `created_date` timestamp -- `created_date` timestamp default '0000-00-00 00:00:00' PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=132 DEFAULT CHARSET=utf8; 

尝试这个:

 CREATE TABLE `test_table` ( `id` INT( 10 ) NOT NULL, `created_at` TIMESTAMP NOT NULL DEFAULT 0, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE = INNODB; 

这是MYSQL 5.5版本的限制。 您需要将版本更新到5.6。

 Error 

我得到这个错误,在MYSQL中添加一个表

表格定义不正确; 在DEFAULT或ON UPDATE子句中只能有一个TIMESTAMP列和CURRENT_TIMESTAMP我的新MYSQL

表看起来像这样。

创build表table_name(col1 int(5)auto_increment主键,col2 varchar(300),col3 varchar(500),col4 int(3),col5 tinyint(2),col6 timestamp默认current_timestamp,col7 timestamp默认current_timestamp on update current_timestamp, col8 tinyint(1)默认0,col9 tinyint(1)默认1);

经过一段时间阅读不同的MYSQL版本和一些谷歌search的变化。 我发现MYSQL版本5.6在版本5.5上有一些变化。

本文将帮助您解决问题。 http://www.oyewiki.com/MYSQL/Incorrect-table-definition-there-can-be-only-one-timestamp-column