一个表中有两个MySQL时间戳列

时间:2011-07-05 00:02:47

标签: mysql

我想创建一个包含“已创建”列和另一个“已更新”列的表。 “created”列将设置为insert并且永不更改。每次更新行时,“已更新”列都会更改。我不想在后续的INSERT或UPDATE语句中混淆这些列中的任何一个。那么如果我从这样的东西开始,我的CREATE TABLE语句应该是什么样的呢?

CREATE TABLE IF NOT EXISTS `mydb`.`mytable` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `updated` TIMESTAMP,
  `created` TIMESTAMP,
  `deleted` TINYINT DEFAULT 0,
  `notes` TEXT DEFAULT '',
  `description` VARCHAR(100)
) TYPE=innodb;

我似乎无法创建包含两个TIMESTAMP列的表。我不关心列是TIMESTAMP还是DATETIME或者其他什么,我只是希望它们由MySQL填充而没有来自插入或更新语句的明确指令。

我希望能够像这样插入:

INSERT INTO `mydb`.`mytable` (notes,description) VALUES ('some note','some description');

并更新如下:

UPDATE `mydb`.`mytable` SET notes=CONCAT(notes,'some more notes') WHERE id=1;

无需在insert或update语句中显式设置“created”列或设置(或重置)“updated”列。

5 个答案:

答案 0 :(得分:7)

尝试这个来创建你的表:

CREATE TABLE IF NOT EXISTS db.test_table
(
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
created DATETIME DEFAULT NULL,
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted TINYINT DEFAULT 0,
notes TEXT DEFAULT NULL,
description VARCHAR(100)
)

请注意

updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

将允许自动更新此字段。

在插入记录之前将其设置为触发器:

DELIMITER $$

CREATE
    /*[DEFINER = { user | CURRENT_USER }]*/
    TRIGGER `db`.`on_before_insert` BEFORE INSERT
    ON `db`.`test_table`
    FOR EACH ROW BEGIN
    SET new.created = NOW();    
    END$$

DELIMITER ;

然后你可以用它来插入:

INSERT INTO db.test_table(description) VALUES ("Description")

并更新您的记录

UPDATE db.test_table SET description = "Description 2" where Id=1

您的创建和更新字段将被适当设置。

答案 1 :(得分:3)

新闻快讯:在mysql中,每次更新行中的任何其他列时,TIMESTAMP列始终会更新为now() - 这是此数据类型的一个特意功能

另一方面,

DATETIME没有这种奇怪的行为 - 这是完全正常的。

答案:created必须为DATETIME,但由于this bug,您还需要一个触发器,如下所示:

CREATE TABLE IF NOT EXISTS mytable (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `updated` TIMESTAMP, -- This will be updated to now(), if you don't set it or set it to null
  `created` DATETIME NOT NULL, -- This will never be magically updated once written
  `deleted` TINYINT DEFAULT 0,
  `notes` TEXT DEFAULT '',
  `description` VARCHAR(100)
) TYPE=innodb;

DELIMITER ~
CREATE TRIGGER mytable_insert_trigger
BEFORE INSERT ON mytable
FOR EACH ROW BEGIN
    SET NEW.created = CURRENT_TIMESTAMP;
END;~
DELIMITER ;

insert into mytable (notes) values ('test');
select * from mytable;
+----+---------------------+---------------------+---------+-------+-------------+
| id | updated             | created             | deleted | notes | description |
+----+---------------------+---------------------+---------+-------+-------------+
|  1 | 2011-07-05 11:48:02 | 2011-07-05 11:48:02 |       0 | test  | NULL        |
+----+---------------------+---------------------+---------+-------+-------------+

答案 2 :(得分:2)

试试这个:

CREATE TABLE IF NOT EXISTS mydb.mytable
(
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    updated DATETIME,
    created TIMESTAMP,
    deleted TINYINT DEFAULT 0,
    notes TEXT DEFAULT '',
    description VARCHAR(100)
) TYPE=innodb;

修改:使用触发器。

CREATE TRIGGER mytable_update
BEFORE UPDATE ON mydb.mytable
    FOR EACH ROW SET NEW.updated = NOW();

答案 3 :(得分:1)

替代方法是更改​​时间戳列的顺序

OR

设置第一列DEFAULT值,如下所示

ALTER TABLE `tblname` CHANGE `first_timestamp_column` 
     `first_timestamp_column` TIMESTAMP NOT NULL DEFAULT 0;

Reference

答案 4 :(得分:0)

不幸的是,MySQL不允许在一个表中有两个TIMESTAMP列。我将使用ON UPDATE CURRENT_TIMESTAMP来更新列,并使用NOW()函数手动创建。