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

时间:2019-04-15 10:56:32

标签: mysql sql timestamp sql-update prepared-statement

当与准备好的语句一起使用时,我在表的更新上遇到了一些问题。 似乎mysql正在更新错误的列,该列甚至未在update命令中指定。

准备:

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列?

1 个答案:

答案 0 :(得分:1)

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

show_from timestamp not null

在这种模式下,每次更新行(其任何列)时,MySQL都会更新该列。 From the manual

如果禁用了explicit_defaults_for_timestamp系统变量,则第一TIMESTAMP列中同时包含DEFAULT CURRENT_TIMESTAMPON UPDATE CURRENT_TIMESTAMP(如果未明确指定两者均未显示)。

该文档建议了以下解决方法:

  
      
  • 使用DEFAULT子句定义列,该子句指定恒定的默认值。

  •   
  • 指定NULL属性。这也会导致该列允许使用NULL值,这意味着您无法分配当前时间戳   通过将列设置为NULL。

  •   

我实际上会建议这样做:

  
      
  • 启用explicit_defaults_for_timestamp系统变量。
  •