MySQL 4.0 中同时具有“创建”和“上次更新”时间戳列

发布于 2024-07-09 10:23:22 字数 740 浏览 5 评论 0原文

我有以下表架构;

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

I have the following table schema;

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;

It fails with the following error:

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

My question is, can I have both of those fields? or do I have to manually set a LastUpdated field during each transaction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

舞袖。长 2024-07-16 10:23:22

来自 MySQL 5.5 文档

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

MySQL 5.6.5 中的更改:

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

From the MySQL 5.5 documentation:

One TIMESTAMP column in a table can have the current timestamp as the default value for initializing the column, as the auto-update value, or both. It is not possible to have the current timestamp be the default value for one column and the auto-update value for another column.

Changes in MySQL 5.6.5:

Previously, at most one TIMESTAMP column per table could be automatically initialized or updated to the current date and time. This restriction has been lifted. Any TIMESTAMP column definition can have any combination of DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses. In addition, these clauses now can be used with DATETIME column definitions. For more information, see Automatic Initialization and Updating for TIMESTAMP and DATETIME.

猥︴琐丶欲为 2024-07-16 10:23:22

有一个技巧可以同时拥有两个时间戳,但是有一点限制。

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

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

请注意,在 insert 期间必须在两列中输入 null

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)  

There is a trick to have both timestamps, but with a little limitation.

You can use only one of the definitions in one table. Create both timestamp columns like so:

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

Note that it is necessary to enter null into both columns during 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)  
梦中的蝴蝶 2024-07-16 10:23:22

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

或者。

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

You can have them both, just take off the "CURRENT_TIMESTAMP" flag on the created field. Whenever you create a new record in the table, just use "NOW()" for a value.

Or.

On the contrary, remove the 'ON UPDATE CURRENT_TIMESTAMP' flag and send the NOW() for that field. That way actually makes more sense.

┊风居住的梦幻卍 2024-07-16 10:23:22

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

If you do decide to have MySQL handle the update of timestamps, you can set up a trigger to update the field on insert.

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

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

抚你发端 2024-07-16 10:23:22

这就是你如何拥有自动& 使用触发器灵活的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 )。
  • 如果您更新,则可以指定lastModified 早于之前的值(“0000-00-00 00:00:00”效果很好),从而允许更新条目如果您正在进行外观更改(修复评论中的拼写错误)并且想要保留旧的最后修改日期。 这不会修改最后修改日期。

This is how can you have automatic & flexible createDate/lastModified fields using triggers:

First define them like this:

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`),
)

Then add these triggers:

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);
  • If you insert without specifying createDate or lastModified, they will be equal and set to the current timestamp.
  • If you update them without specifying createDate or lastModified, the lastModified will be set to the current timestamp.

But here's the nice part:

  • If you insert, you can specify a createDate older than the current timestamp, allowing imports from older times to work well (lastModified will be equal to createDate).
  • If you update, you can specify a lastModified older than the previous value ('0000-00-00 00:00:00' works well), allowing to update an entry if you're doing cosmetic changes (fixing a typo in a comment) and you want to keep the old lastModified date. This will not modify the lastModified date.
凉风有信 2024-07-16 10:23: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)
)

As of MySQL 5.6 its easy-peasy... give it a try:

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)
)
醉酒的小男人 2024-07-16 10:23:22

这个问题似乎在 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

This issue seemed to have been resolved in MySQL 5.6. I have noticed this until MySQL 5.5; here is an example code:

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;

Running this on MySQL 5.5 gives:

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

Running this on MySQL 5.6

0 row(s) affected   0.093 sec
浅暮の光 2024-07-16 10:23:22
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 /

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/

淑女气质 2024-07-16 10:23:22

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

i think this is the better query for stamp_created and 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() 
); 

because when the record created, stamp_created should be filled by now() and stamp_updated should be filled by '0000-00-00 00:00:00'

太阳哥哥 2024-07-16 10:23:22

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

   create table users( 
      id integer not null auto_increment primary key, 
      created_date timestamp default now(), 
      modified_date timestamp default now() on update now() 
    ); 

this will add two column for creation and updation.
both will get updated while inserting and updating.

   create table users( 
      id integer not null auto_increment primary key, 
      created_date timestamp default now(), 
      modified_date timestamp default now() on update now() 
    ); 
意中人 2024-07-16 10:23:22

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

CREATE TABLE `Posts` (
  `modified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) 

For mysql 5.7.21 I use the following and works fine:

CREATE TABLE `Posts` (
  `modified_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) 
悲喜皆因你 2024-07-16 10:23:22

我的网络主机停留在 mysql 5.1 版本上,因此像我这样无法升级的人可以按照以下说明操作:

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

My web host is stuck on version 5.1 of mysql so anyone like me that doesn't have the option of upgrading can follow these directions:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文