185

为什么在 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 子句中只能有一个带有 CURRENT_TIMESTAMP 的 TIMESTAMP 列

4

9 回答 9

177

这个限制,只是由于历史,代码遗留的原因,在最近的 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

于 2013-07-05T23:40:41.850 回答
40

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

简而言之:

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

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

干杯!

于 2010-12-20T13:20:16.447 回答
38

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

这篇文章提供了详细的解决方法: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() 
);

请注意,在“插入”期间需要在两列中输入空值:

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) 
于 2011-11-16T07:06:00.923 回答
16

确实是实施错误。

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

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

在创建时插入 NULL:

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

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

在 MySQL 中,表的第一个 TIMESTAMP 列同时获取DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP属性,如果没有为它提供属性。这就是为什么带有属性的 TIMESTAMP 列必须首先出现,否则您会收到此线程中描述的错误。

于 2012-11-24T18:23:50.647 回答
14
  1. 将列的数据类型更改为日期时间
  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 ;
于 2011-04-21T12:20:55.587 回答
3

结合各种答案:

在 MySQL 5.5 中,DEFAULT CURRENT_TIMESTAMP不能ON UPDATE CURRENT_TIMESTAMP添加,DATETIME只能添加到TIMESTAMP.

规则:

1)TIMESTAMP每个表最多可以自动(或手动[我的添加])初始化或更新为当前日期和时间。(MySQL 文档)。

所以只能有TIMESTAMP一个CURRENT_TIMESTAMPin DEFAULTorON UPDATE子句

NOT NULL TIMESTAMP2)没有明确DEFAULT值 like的第一列created_date timestamp default '0000-00-00 00:00:00'将被隐式赋予 a DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,因此TIMESTAMP不能CURRENT_TIMESTAMPDEFAULTorON 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;
于 2017-02-17T22:44:38.737 回答
1

对您而言,一个解决方法可能是将其放在 UpdatedDate 字段上,并有一个触发器,仅当 AdditionalDate 为空时才使用 UpdatedDate 值更新 AdditionalDate 字段。

于 2010-12-20T17:07:36.347 回答
0

试试这个:

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;
于 2014-01-30T11:03:06.313 回答
0

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

Error

我在 MYSQL 中添加表时遇到此错误

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

表看起来像这样。

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

经过一段时间阅读不同 MYSQL 版本的变化和一些谷歌搜索。我发现在 MYSQL 5.6 版中对 5.5 版进行了一些更改。

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

于 2016-07-31T20:08:42.613 回答