use*_*195 3 php mysql timestamp on-duplicate-key
我有一个表格作品集,时间戳设置为自动更新.
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Run Code Online (Sandbox Code Playgroud)
PHP中的PDO语句不会导致时间戳更新.
$statement = $this->connection->prepare("
INSERT INTO folio(publication, productId)
VALUES(:publication, :productId)
ON DUPLICATE KEY UPDATE
id=LAST_INSERT_ID(id), publication=:publication, productId=:productId");
Run Code Online (Sandbox Code Playgroud)
以下手动方法有效但不可取.
$statement = $this->connection->prepare(
"INSERT INTO folio(publication, productId)
VALUES(:publication, :productId)
ON DUPLICATE KEY UPDATE
id=LAST_INSERT_ID(id), publication=:publication, productId=:productId, timestamp=NOW()");
Run Code Online (Sandbox Code Playgroud)
更新:这是我的作品集表结构
CREATE TABLE `folio` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`publication` varchar(255) DEFAULT NULL,
`productId` varchar(255) DEFAULT NULL,
`timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_folio` (`publication`,`productId`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
更新2:将timestamp设置为not null后的表结构
CREATE TABLE `folio` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`publication` varchar(255) DEFAULT NULL,
`productId` varchar(255) DEFAULT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_folio` (`publication`,`productId`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
据我所知,您的查询问题可能是因为您使timestamp字段可以为空
`timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Run Code Online (Sandbox Code Playgroud)
尝试使其为NOT NULL - 因为你有它的有效默认值,MySQL不会抱怨你没有提供查询中的值:
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Run Code Online (Sandbox Code Playgroud)
此外,尝试将timestamp字段重命名为更合理的内容,例如:
`changed_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Run Code Online (Sandbox Code Playgroud)
此外,正如我的评论中所述 - 您不需要提供ON DUPLICATE KEY 部分中的所有字段,而只需要提供数据字段:
INSERT INTO folio(publication, productId)
VALUES(:publication, :productId)
ON DUPLICATE KEY UPDATE
publication=:publication,
productId=:productId
Run Code Online (Sandbox Code Playgroud)
这是因为如果MySQL检测到您有重复的键条件,它将不会插入新行,而是更新现有的行,因此id列必须保持不变.
UPDATE
似乎没有更新timestamp列是一个记录的行为 - TIMESTAMP列的MySQL手册
引用所需的段落:
如果该列是自动更新的,则当该行中任何其他列的值从其当前值更改时,它将自动更新为当前时间戳.如果所有其他列都设置为其当前值,则列保持不变.要防止列在其他列更改时更新,请将其显式设置为其当前值.要更新列,即使其他列未更改,也要将其显式设置为应具有的值(例如,将其设置为CURRENT_TIMESTAMP).
因此,您满足所有条件:) - 当您插入记录时,应正确填充时间戳.但是当您按顺序提供重复值来更新时timestamp,MySQL会看到您设置行中已存在的值(否则它不会重复),因此它不会更新timestamp列.
因此,解决方案非常简单,您已经找到了 - timestamp只要您提供重复值,就会明确更新列,例如:
INSERT INTO folio(publication, productId)
VALUES(:publication, :productId)
ON DUPLICATE KEY UPDATE
`timestamp` = NOW()
Run Code Online (Sandbox Code Playgroud)
无论如何,使timestampNOT NULL不会受到伤害.