我已将时间戳设置为自动更新的表格作品集。
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
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");
遵循手动方法,但不可取。
$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()");
更新:这是我的作品集表结构
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;
更新2:将时间戳设置为非空后的表结构
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;
答案 0 :(得分:7)
据我所知,您的查询问题可能是因为您将timestamp
字段视为可空
`timestamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
尝试将其设为NOT NULL - 因为您有有效的默认值,MySQL不会抱怨您没有在查询中提供该值:
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
另外,尝试将timestamp
字段重命名为更合理的字段,例如:
`changed_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
此外,正如我的评论中所述 - 您不需要提供ON DUPLICATE KEY
部分中的所有字段,但只提供数据字段:
INSERT INTO folio(publication, productId)
VALUES(:publication, :productId)
ON DUPLICATE KEY UPDATE
publication=:publication,
productId=:productId
这是因为如果MySQL检测到您有重复的密钥条件,它不会插入新行,但会更新现有的行,因此id
列必须保持不变。
<强>更新强>
似乎未更新timestamp
列是一种记录在案的行为 - MySQL manual for TIMESTAMP columns
引用所需的段落:
如果列自动更新,则当行中任何其他列的值从其当前值更改时,它会自动更新为当前时间戳。如果所有其他列都设置为其当前值,则列保持不变。要防止列在其他列更改时更新,请将其显式设置为其当前值。要更新列,即使其他列未更改,也要将其显式设置为应具有的值(例如,将其设置为CURRENT_TIMESTAMP)。
所以,你满足所有条件:) - 当你插入记录时,应该正确填充时间戳。
但是当您按顺序提供重复值以更新timestamp
时,MySQL会看到您设置行中已存在的值(否则它不会重复),因此它不会更新{{ 1}}列。
因此,解决方案非常简单并且已经找到了 - 只要您提供重复值,就会明确更新timestamp
列,例如:
timestamp
无论如何,使INSERT INTO folio(publication, productId)
VALUES(:publication, :productId)
ON DUPLICATE KEY UPDATE
`timestamp` = NOW()
NOT NULL不会受到伤害。
答案 1 :(得分:1)
如果新的INSERT值与重复行中的旧值相同,那么显然MySQL不执行UPDATE,因此不会触发ON UPDATE CURRENT_TIMESTAMP。 :(
因此,作为一种尴尬的解决方法,您可以向表中添加一个虚拟字段,强制发生UPDATE(如果是重复的id):
$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,
dummy = NOT dummy
");
...正如用户评论中所述:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
答案 2 :(得分:0)
只是
在创建重复键更新时插入your_table(a,b)值(?,?)= current_timestamp
无论好坏,MySQL 都不会 ,无论如何,在插入唯一类型调用的情况下,默认更新时间戳都不会。
您使用的是重复插入,替换还是忽略插入这三个中的哪个都没关系
无论您在字段,表格或其他任何内容上使用哪种设置或质量,都没有任何区别
只需在末尾添加created = current_timestamp
即可手动完成。
很遗憾,就是这样!