MySQL 5.7 准备好的语句更新了错误的时间戳列

MySQL 5.7 prepared statements updating the wrong timestamp column

我在 table 上的更新与准备好的语句一起使用时遇到了一些问题。 似乎 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;

returns:

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;

returns:

1    2019-04-15 12:54:27    2019-02-11 13:12:11

为什么 mysql 更新了 show_from 列?

该列声明时间戳,不为空:

show_from timestamp not null

在此模式下,MySQL 将在每次更新行(其任何列)时更新该列。 From the manual:

如果 explicit_defaults_for_timestamp 系统变量被禁用,第一个 TIMESTAMP 列同时具有 DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP 如果两者都没有明确指定。

文档建议了解决方法,例如:

  • Define the column with a DEFAULT clause that specifies a constant default value.

  • Specify the NULL attribute. This also causes the column to permit NULL values, which means that you cannot assign the current timestamp by setting the column to NULL.

我实际上会推荐这个:

  • Enable the explicit_defaults_for_timestamp system variable.