MySQL ON UPDATE CURRENT_TIMESTAMP 未更新

Posted

技术标签:

【中文标题】MySQL ON UPDATE CURRENT_TIMESTAMP 未更新【英文标题】:MySQL ON UPDATE CURRENT_TIMESTAMP not updating 【发布时间】:2011-07-31 02:09:15 【问题描述】:

我有一个如下所示的表格:

CREATE TABLE IF NOT EXISTS `Hosts` (
`id` int(128) NOT NULL AUTO_INCREMENT,
`IP` varchar(15) NOT NULL DEFAULT '',
`Port` varchar(5) NOT NULL DEFAULT '',
`Password` varchar(32) NOT NULL DEFAULT '',
`Username` varchar(32) NOT NULL DEFAULT '',
`Tid` varchar(32) NOT NULL DEFAULT '',
`EquipType` varchar(64) NOT NULL DEFAULT '',
`Version` varchar(128) DEFAULT NULL,
`Status` varchar(10) NOT NULL DEFAULT '',
`Location` varchar(128) NOT NULL DEFAULT '',
`Lastconnection` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
`Lastbackup` date NOT NULL DEFAULT '0000-00-00',
`Backupstatus` varchar(64) NOT NULL DEFAULT '',
`Backupmsg` text,
`Backupfile` varchar(30) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `IP` (`IP`),
KEY `Tid` (`Tid`),
KEY `EquipType` (`EquipType`),
KEY `Status` (`Status`),
KEY `Lastbackup` (`Lastbackup`),
KEY `Backupstatus` (`Backupstatus`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=716 ;

在我看来,这意味着每当更新一行时,“Lastconnection”字段都应该带有当前时间戳。但是,当我运行类似:

update Hosts set Backupstatus = 'FAIL',  Backupmsg = 'Connection timed out' where Tid = 'SITE001'

上次连接保持“0000-00-00 00:00:00”。我没有看到数据库问题,或者我完全误解了“ON UPDATE CURRENT_TIMESTAMP”子句。

【问题讨论】:

你的版本是什么?我只是因为这个错误报告才问:bugs.mysql.com/bug.php?id=28904 您报告的 ts 列中填充了“0000-00-00 00:00:00”确实与我的猜测相矛盾。与 NO_ZERO_DATE 模式有关,但请查看dev.mysql.com/doc/refman/5.0/en/… 我想可能是这样。许多行都被正确标记,但有些可能有重复的值。我会尝试升级。 对查询中的日期时间列使用 null 对我有用。 根据dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html,当前时间戳将仅在行中的值之一更改时更新(即,如果所有值保持不变,lastconnection 列也不会更新,即使您运行UPDATE查询) 【参考方案1】:

您必须记住,如果没有值在更新时更改,则不会设置当前时间戳,

您必须在查询NOW() 中设置值以设置当前时间戳!!!

update Hosts set Backupstatus = 'FAIL',Lastconnection = NOW() , Backupmsg = 'Connection timed out' where Tid = 'SITE001'

请记住,必须更改值才能更改当前时间戳。

【讨论】:

【参考方案2】:

可能是更新语句没有改变任何东西。如果带有Tid = 'SITE001' 的行已经将Backupstatus 设置为'FAIL'Backupmsg 设置为'Connection timed out'(可能是由以前的一些备份尝试设置的),那么MySQL 将跳过这一行,因此不会更改Lastconnection时间戳。

另外,我认为ON UPDATE CURRENT_TIMESTAMP 更像是一种管理功能,用于跟踪数据更改。作为程序员,我会明确添加时间戳更新:

update Hosts set Backupstatus = 'FAIL', Backupmsg = 'Connection timed out', Lastconnection = NOW() where Tid = 'SITE001'.

【讨论】:

这是一个常见的错误,“on update”子句更具管理性,不应该这样使用。如果数据没有真正的变化,它就不会起作用。【参考方案3】:

你有没有尝试在更新时为该字段使用 null?

您也可以尝试将默认值设置为CURRENT_TIMESTAMP,而不是0000-00-00 00:00:00

尽管如此,每当我想要创建和更新时间时,我总是使用以下内容:

...
CREATED timestamp NOT NULL default '0000-00-00 00:00:00',
UPDATED timestamp NOT NULL default now() on update now(),
....

我使用now(),因为它是CURRENT_TIMESTAMP 的别名,而且它更短。最后表结构得到CURRENT_TIMESTAMP,不用担心。

CREATED 字段的技巧是记住在 INSERT 语句的两个字段上都使用 null,对于 UPDATE 语句,它不是必需的:

INSERT INTO mytable (field1, field2, created, updated)
VALUES ('foo', 'bar', null, null);

【讨论】:

更多解释...dev.mysql.com/doc/refman/5.0/en/timestamp.html 我必须在更新语句中将时间戳字段设置为null。现在每次更新字段时(即使数据并没有真正改变)。 是的,NOW() 还存在其他同义词,例如 LOCALTIME、LOCALTIME()、LOCALTIMESTAMP、LOCALTIMESTAMP()、CURRENT_TIMESTAMP 和 CURRENT_TIMESTAMP() - dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html 使用UTC_TIMESTAMP() 来避免 MySQL 服务器时区与您的应用程序不同的问题不是更好吗?【参考方案4】:

如果您希望记录在记录发生更改时自动更新时间戳,以下是您需要完成的四个简单步骤(可以一步完成,具体取决于您是使用命令行还是 GUI 进行管理) :

    创建字段以保存自动更新的时间戳(我通常称我的时间戳为“已修改”)。 将字段类型指定为“TIMESTAMP” 将默认字段指定为“CURRENT_TIMESTAMP” 将字段 Extra 指定为“ON UPDATE CURRENT_TIMESTAMP”

现在,只要记录更新,包含您的时间戳的字段将始终更新为当前时间戳。

【讨论】:

这只是重申其他答案中已经提供的信息。 简明扼要,易于阅读....它帮助了我!我只是在插入未更新时才获得更新。我错过了第 4 步。【参考方案5】:

要指定自动属性,请使用DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP 子句。子句的顺序无关紧要。如果两者都存在于列定义中,则任何一个都可以先出现。 CURRENT_TIMESTAMP 的任何同义词都与 CURRENT_TIMESTAMP 具有相同的含义。它们是CURRENT_TIMESTAMP()NOW()LOCALTIMELOCALTIME()LOCALTIMESTAMPLOCALTIMESTAMP()

DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP 的使用特定于 TIMESTAMPDEFAULT 子句也可用于指定常量(非自动)默认值;例如,DEFAULT 0DEFAULT '2000-01-01 00:00:00'

如果启用了NO_ZERO_DATE SQL 模式,DEFAULT 0 将不起作用,因为该模式会导致“零”日期值(例如,指定为 0 '0000-00-00 00:00:00')为被拒绝。请注意TRADITIONAL SQL 模式包括NO_ZERO_DATE

此外,您可以将任何TIMESTAMP 列初始化或更新为当前日期和时间,方法是为其分配一个NULL 值,除非它已使用NULL 属性定义以允许NULL 值。

【讨论】:

我是否遗漏了什么,或者这个答案是说要执行 OP 已经 正在执行的操作,但无论如何都失败了?他说带有ON UPDATE CURRENT_TIMESTAMP 的时间戳字段在更新时不会改变,不是吗?关于时间戳的良好一般信息;这个问题的答案不好。

以上是关于MySQL ON UPDATE CURRENT_TIMESTAMP 未更新的主要内容,如果未能解决你的问题,请参考以下文章

sql UPDATE ON DUPLICATE KEY造成MYSQL死锁现场

mysql ON DUPLICATE KEY UPDATE

MySQL外键约束On Delete和On Update的使用

mysql ON DUPLICATE KEY UPDATE ;

mysql中的ON DUPLICATE KEY UPDATE

MySQL外键约束On Delete和On Update的使用