在MySQL 4.0中同时具有Created和Last Updated时间戳列

时间:2008-11-06 04:41:16

标签: mysql mysql-error-1293

我有以下表格架构;

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字段?

11 个答案:

答案 0 :(得分:113)

From the MySQL 5.5 documentation

  

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

Changes in MySQL 5.6.5

  

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

答案 1 :(得分:83)

There is a trick有两个时间戳,但有一点限制。

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

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)

{{1}}

答案 2 :(得分:27)

您可以同时使用它们,只需在创建的字段上取下“CURRENT_TIMESTAMP”标志即可。无论何时在表中创建新记录,只需使用“NOW()”作为值。

或者

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

答案 3 :(得分:25)

如果你决定让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

答案 4 :(得分:23)

这就是你如何拥有自动&amp;使用触发器灵活创建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将设置为当前时间戳。

但这是很好的部分:

  • 如果您插入,则可以指定 createDate早于当前时间戳,从而允许从较旧时间导入效果良好(lastModified将等于createDate)。 / LI>
  • 如果你更新,你可以指定 lastModified比上一个值更早('0000-00-0000:00 00:00'效果很好),允许如果您正在进行整容更改(修复评论中的拼写错误)并且您希望保留旧的lastModified 日期,则更新条目。这不会修改lastModified日期。

答案 5 :(得分:21)

从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)
)

答案 6 :(得分: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

答案 7 :(得分: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() 
); 

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

答案 8 :(得分:2)

我认为这是对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'

填写

答案 9 :(得分:1)

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

CREATE TABLE Posts(   modified_at时间戳NOT NOT DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,   created_at时间戳NOT NULL DEFAULT CURRENT_TIMESTAMP )

答案 10 :(得分:0)

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

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