为什么DEFAULT子句中只有一个TIMESTAMP列和CURRENT_TIMESTAMP?

rip*_*234 176 mysql timestamp mysql-error-1293

为什么在DEFAULT或ON UPDATE子句中只能有一个TIMESTAMP列和CURRENT_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;
Run Code Online (Sandbox Code Playgroud)

导致的错误:

错误代码:1293

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

aug*_*tin 167

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

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

以前,每个表最多只能有一个TIMESTAMP列自动初始化或更新到当前日期和时间.这一限制已被取消.任何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

  • 对于旧版本?请查看http://stackoverflow.com/a/267675/2009536 (2认同)

Lac*_*lev 40

很久以前我也想知道.我在历史记录中搜索了一下,我认为这篇文章:http://lists.mysql.com/internals/34919代表了MySQL的半官方立场(在Oracle干预之前;))

简而言之:

此限制仅源于此功能当前在服务器中实现的方式,并且没有其他原因存在.

所以他们的解释是"因为它是这样实现的".听起来不是很科学.我猜这一切都来自一些旧代码.这在上面的线程中建议:"从仅第一个时间戳字段被自动设置/更新时结转".

干杯!

  • 另一个伟大的MySQL限制让我们享受! (46认同)

Sca*_*ett 34

我们可以为时间戳指定默认值以避免此问题.

这篇文章给出了详细的解决方法: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() 
);
Run Code Online (Sandbox Code Playgroud)

请注意,在"插入"期间必须在两列中输入空值:

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) 
Run Code Online (Sandbox Code Playgroud)


moo*_*oli 16

确实是一个实施错误.

MySQL中的本机方法是自己更新创建日期(如果需要)并让MySQL担心时间戳, update date ? update date : creation date如下所示:

CREATE TABLE tracked_data( 
  `data` TEXT,
  `timestamp`   TIMESTAMP,
  `creation_date` TIMESTAMP                                   
) ENGINE=INNODB; 
Run Code Online (Sandbox Code Playgroud)

在创建时插入NULL:

INSERT INTO tracked_data(`data`,`creation_date`) VALUES ('creation..',NULL);
Run Code Online (Sandbox Code Playgroud)

默认情况下,时间戳的NULL值作为CURRENT_TIMESTAMP进行交互.

在MySQL中,如果没有给出属性,则表的第一个TIMESTAMP列将获取属性DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP属性.这就是具有属性的TIMESTAMP列必须首先出现的原因,或者您得到此线程中描述的错误.


Fen*_*ing 13

  1. 将列的数据类型更改为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 ;
Run Code Online (Sandbox Code Playgroud)