有人可以解释为什么会发生以下情况吗?当我运行此语句时:
CREATE TABLE `MyTable2` (
`id` int(10) unsigned NOT NULL,
`start` timestamp NOT NULL,
`cTime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
);
Run Code Online (Sandbox Code Playgroud)
我创建了我的表。但是当我运行这个时:
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`)
);
Run Code Online (Sandbox Code Playgroud)
我收到一条错误消息:
[42000][1067] Invalid default value for 'end'
Run Code Online (Sandbox Code Playgroud)
我错过了什么?这是预期的行为吗?
[更新]:这里似乎有一个提交的错误https://bugs.mysql.com/bug.php?id=80163但我无法从描述中做出任何事情。静音警告和/或更改 sql_mode 不是解决方案,因为它会更改所创建表的语义(两个时间戳列不为空且没有默认值)。
【更新】:我服务器上的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
Run Code Online (Sandbox Code Playgroud)
[解决方案/说明]:原来在这里https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp详细解释了这种行为。为了获得预期的语义,我必须sysvar_explicit_defaults_for_timestamp在我的服务器配置中启用。
我同意这有点隐藏,mysql 可以更明确地说明这一点。Mysql时间戳初始化手册说:
使用 ON UPDATE CURRENT_TIMESTAMP 子句但没有 DEFAULT 子句时,列会自动更新为当前时间戳,但没有默认值的当前时间戳。
这种情况下的默认值是类型相关的。TIMESTAMP 的默认值为 0,除非使用 NULL 属性定义,在这种情况下,默认值为 NULL。
突出显示的部分适用于您:从第二个时间戳字段开始,隐式默认值为 0,这与 '0000-00-00 00:00:00'. 您启用了禁止此默认值的严格且无零日期sql 模式。
但是,第一个时间戳字段被分配current_timestamp()为默认值(它被特殊对待),这就是为什么第一个查询通过您当前的 sql 模式设置。
使第二个时间戳字段可为空或更改您的 sql 模式设置。前者是首选方法。
| 归档时间: |
|
| 查看次数: |
1323 次 |
| 最近记录: |