132

我有以下表格架构;

CREATE TABLE `db1`.`sms_queue` (
  `Id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  `Message` VARCHAR(160) NOT NULL DEFAULT 'Unknown Message Error',
  `CurrentState` VARCHAR(10) NOT NULL DEFAULT 'None',
  `Phone` VARCHAR(14) DEFAULT NULL,
  `Created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `LastUpdated` TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  `TriesLeft` tinyint NOT NULL DEFAULT 3,
  PRIMARY KEY (`Id`)
)
ENGINE = InnoDB;

它失败并出现以下错误:

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause.

我的问题是,我可以同时拥有这两个领域吗?还是我必须在每次交易期间手动设置 LastUpdated 字段?

4

12 回答 12

136

MySQL 5.5文档

表中的一个 TIMESTAMP 列可以将当前时间戳作为初始化该列的默认值、作为自动更新值,或两者兼而有之。不可能将当前时间戳设为一列的默认值,而将另一列的自动更新值设为默认值。

MySQL 5.6.5的变化

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

于 2008-11-06T04:52:08.260 回答
89

有两个时间戳的技巧,但有一点限制。

您只能在一张表中使用其中一种定义。像这样创建两个时间戳列:

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() 
); 

请注意,有必要在以下null期间输入两列insert

mysql> insert into test_table(stamp_created, stamp_updated) values(null, null); 
Query OK, 1 row affected (0.06 sec)

mysql> select * from test_table; 
+----+---------------------+---------------------+ 
| 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)  
于 2009-04-30T15:48:48.530 回答
27

您可以同时拥有它们,只需在创建的字段上去掉“CURRENT_TIMESTAMP”标志。每当您在表中创建新记录时,只需使用“NOW()”作为值。

或者。

相反,删除“ON UPDATE CURRENT_TIMESTAMP”标志并为该字段发送 NOW()。这种方式实际上更有意义。

于 2008-11-06T04:45:36.837 回答
27

如果你决定让 MySQL 处理时间戳的更新,你可以设置一个触发器来更新插入时的字段。

CREATE TRIGGER <trigger_name> BEFORE INSERT ON <table_name> FOR EACH ROW SET NEW.<timestamp_field> = CURRENT_TIMESTAMP;

MySQL 参考:http ://dev.mysql.com/doc/refman/5.0/en/triggers.html

于 2011-06-24T15:53:26.387 回答
23

这就是您如何使用触发器拥有自动和灵活的 createDate/lastModified 字段:

首先像这样定义它们:

CREATE TABLE `entity` (
  `entityid` int(11) NOT NULL AUTO_INCREMENT,
  `createDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `lastModified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `name` varchar(255) DEFAULT NULL,
  `comment` text,
  PRIMARY KEY (`entityid`),
)

然后添加这些触发器:

DELIMITER ;;
CREATE trigger entityinsert BEFORE INSERT ON entity FOR EACH ROW BEGIN SET NEW.createDate=IF(ISNULL(NEW.createDate) OR NEW.createDate='0000-00-00 00:00:00', CURRENT_TIMESTAMP, IF(NEW.createDate<CURRENT_TIMESTAMP, NEW.createDate, CURRENT_TIMESTAMP));SET NEW.lastModified=NEW.createDate; END;;
DELIMITER ;
CREATE trigger entityupdate BEFORE UPDATE ON entity FOR EACH ROW SET NEW.lastModified=IF(NEW.lastModified<OLD.lastModified, OLD.lastModified, CURRENT_TIMESTAMP);
  • 如果您在未指定 createDate 或 lastModified 的情况下插入,则它们将相等并设置为当前时间戳。
  • 如果您在未指定 createDate 或 lastModified 的情况下更新它们,则 lastModified 将设置为当前时间戳。

但这是很好的部分:

  • 如果您insert,您可以指定比当前时间戳更早的 createDate,从而允许从更早的时间进行导入(lastModified 将等于 createDate)。
  • 如果你update,你可以指定一个比前一个值更旧的 lastModified('0000-00-00 00:00:00' 效果很好),如果你正在进行外观更改,则允许更新条目(修复评论中的错字) 并且您想保留旧的 lastModified日期。这不会修改 lastModified 日期。
于 2013-05-07T08:14:17.300 回答
22

从 MySQL 5.6 开始,它很容易...试一试:

create table tweet ( 
    id integer not null auto_increment primary key, 
    stamp_created timestamp default now(), 
    stamp_updated timestamp default now() on update now(),
    message varchar(163)
)
于 2013-12-03T09:45:59.667 回答
4

这个问题似乎在 MySQL 5.6 中得到了解决。直到 MySQL 5.5,我才注意到这一点;这是一个示例代码:

DROP TABLE IF EXISTS `provider_org_group` ;
CREATE TABLE IF NOT EXISTS `provider_org_group` (
  `id` INT NOT NULL,
  `name` VARCHAR(100) NOT NULL,
  `type` VARCHAR(100) NULL,
  `inserted` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `insert_src_ver_id` INT NULL,
  `updated` TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP,
  `update_src_ver_id` INT NULL,
  `version` INT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC),
  UNIQUE INDEX `name_UNIQUE` (`name` ASC))
ENGINE = InnoDB;

在 MySQL 5.5 上运行它会给出:

ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause

在 MySQL 5.6 上运行它

0 row(s) affected   0.093 sec
于 2013-11-14T17:30:05.813 回答
4
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() 
); 

来源:http://gusiev.com/2009/04/update-and-create-timestamps-with-mysql/

于 2016-02-09T11:50:13.527 回答
3

我认为这是对 stamp_created 和 stamp_updated 的更好查询

CREATE TABLE test_table( 
    id integer not null auto_increment primary key, 
    stamp_created TIMESTAMP DEFAULT now(), 
    stamp_updated TIMESTAMP DEFAULT '0000-00-00 00:00:00' ON UPDATE now() 
); 

因为当记录创建时,stamp_created应该由now()并且stamp_updated应该由'0000-00-00 00:00:00'

于 2018-05-05T14:15:27.820 回答
2

对于 mysql 5.7.21,我使用以下内容并且工作正常:

CREATE TABLE Posts( modified_attimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_attimestamp NOT NULL DEFAULT CURRENT_TIMESTAMP)

于 2018-06-14T14:58:03.427 回答
0

我的虚拟主机卡在 mysql 5.1 版上,所以像我这样没有升级选项的人可以按照以下说明进行操作:

http://joegornick.com/2009/12/30/mysql-created-and-modified-date-fields/

于 2018-03-26T16:15:36.803 回答
0

这将添加两列用于创建和更新。两者都会在插入和更新时得到更新。

   create table users( 
      id integer not null auto_increment primary key, 
      created_date timestamp default now(), 
      modified_date timestamp default now() on update now() 
    ); 
于 2021-12-09T13:15:52.223 回答