mysql - MySQL 5.7 准备好的语句更新了错误的时间戳列
问题描述
当与准备好的语句一起使用时,我在更新表时遇到了一些问题。似乎 mysql 正在更新一个错误的列,该列甚至没有在更新命令中指定。
准备:
drop table test1;
create table test1(
id int not null,
show_from timestamp not null,
updated_at timestamp NULL DEFAULT NULL
);
insert into test1(id, show_from, updated_at) values(1, '2018-01-11 12:10:11.19808', '2019-04-15 11:50:00.704748');
在一批中执行此操作:
UPDATE test1 SET show_from='2018-04-15 11:50:00.704748' WHERE id=1;
SELECT * FROM test1;
返回:
1 2018-04-15 13:50:01 2019-04-15 13:50:01
正如预期的那样。
现在在一批中执行此操作:
PREPARE stmt1 FROM 'UPDATE test1 SET updated_at=? WHERE id=?';
SET @s1='2019-02-11 12:12:11.19808';
SET @s2=1;
EXECUTE stmt1 USING @s1, @s2;
DEALLOCATE PREPARE stmt1;
SELECT * FROM test1;
返回:
1 2019-04-15 12:54:27 2019-02-11 13:12:11
为什么 mysql 更新 show_from 列?
解决方案
该列被声明为时间戳,而不是 null:
show_from timestamp not null
在这种模式下,MySQL 将在每次更新行(它的任何列)时更新列。从手册:
如果explicit_defaults_for_timestamp
系统变量被禁用,则第一TIMESTAMP
列两者都有DEFAULT CURRENT_TIMESTAMP
,ON UPDATE CURRENT_TIMESTAMP
如果两者都没有明确指定。
该文档提出了一些解决方法,例如:
使用指定常量默认值的 DEFAULT 子句定义列。
指定 NULL 属性。这也会导致列允许 NULL 值,这意味着您不能通过将列设置为 NULL 来分配当前时间戳。
我实际上会推荐这个:
- 启用
explicit_defaults_for_timestamp
系统变量。
推荐阅读
- vbscript - 如何通过 VBScript 在文本文件中保存非拉丁字符?
- excel - 试图忽略 Excel 列中的零值
- python - 使用坐标(基因)文件的脚本
- android - Android 语音转文本查询
- java - JavaFx 如何使用二维数组向 GridPane 添加按钮?
- angular - '可观察的
>' 不可分配给类型 'Observable - .net - .NET API 上的基本 SSO
- wordpress - 高 CPU 使用率和限制超出问题
- c++ - CMake AutoMoc 导致重复符号
- node.js - 如何解决 npm deprecation 安装错误