MySQL服务器5.7.17,表上的多个时间戳不为空字段

时间:2017-02-03 09:03:09

标签: mysql

有人可以解释为什么会发生以下情况吗? 当我运行这个陈述时:

CREATE TABLE `MyTable2` (
   `id` int(10) unsigned NOT NULL,
   `start` timestamp NOT NULL,
   `cTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`)
);

我创建了我的表格。但是当我运行这个时:

CREATE TABLE `MyTable2` (
   `id` int(10) unsigned NOT NULL,
   `start` timestamp NOT NULL,
   `end` timestamp NOT NULL,
   `cTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
   PRIMARY KEY (`id`)
);

我收到错误声明:

[42000][1067] Invalid default value for 'end'

我错过了什么?这是预期的行为吗?

[更新]:似乎这里有一个提交的错误https://bugs.mysql.com/bug.php?id=80163,但我无法从描述中做出任何改变。沉默警告和/或更改sql_mode不是解决方案,因为它更改了创建的表的语义(两个时间戳列不为null而没有默认值)。

[更新]:我服务器上的sql_mode如下:

ONLY_FULL_GROUP_BY,NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,
NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

[解决方案/说明]: 原来这里https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp详细解释了这种行为。为了获得预期的语义,我必须在我的服务器配置中启用sysvar_explicit_defaults_for_timestamp

1 个答案:

答案 0 :(得分:3)

我同意这有点隐藏,而且mysql可能更明确。 timestamp initialisation上的Mysql手册说:

  

使用ON UPDATE CURRENT_TIMESTAMP子句但没有DEFAULT子句,   列自动更新为当前时间戳,但不会   将当前时间戳设为默认值。

     

此情况下的默认值取决于类型。 TIMESTAMP的默认值为   0除非使用NULL属性定义,在这种情况下默认值为   NULL。

突出显示的部分适用于您:第二个时间戳字段的隐式默认值为0,即the same as '0000-00-00 00:00:00'。您启用了strict and no zero date sql模式,禁止使用此默认值。

但是,第一个时间戳字段默认为current_timestamp()(特殊处理),这就是第一个查询通过当前sql模式设置的原因。

使第二个时间戳字段可以为空或更改您的SQL模式设置。前者是首选方法。