MySQL 5.5和5.6的默认值

14

我希望对MySQL 5.5和5.6中默认值的行为有些澄清。假设我们在一个MySQL 5.5服务器上有以下表:

CREATE TABLE `test` (
`TestColumn` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=INNODB DEFAULT CHARSET=utf8;

我能够毫无问题地运行以下查询:

INSERT INTO `test` VALUES (NULL);

这将创建以下行:

 TestColumn
 2014-02-20 14:55:05

现在,如果我在一个MySQL 5.6服务器上重复进行相同的测试,则插入操作将失败:

Error Code: 1048
Column 'TestColumn' cannot be null

我理解在5.6中时间戳的自动初始化方式已更改(http://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html),但我无法弄清楚如何在5.6中复制5.5中看到的行为。

不确定是否重要,但我们的5.6服务器已将explicit_defaults_for_timestamp设置为ON。

理想情况下,我想要的是解决方案,但如果有人能更好地理解并解释它,那也很有用。

谢谢。

编辑:我们正在使用MySQL 5.6.13


1
第一个插入本来就不应该成功。你是让数据库将NULL值放入非空列,所以5.6拒绝了这样做。 - user330315
@user1095982 MySQL 5.5.32测试,MySQL 5.6.10。 - bear
@Shamil,你将explicit_defaults_for_timestamp设置为什么了? - BombTodley
1
@Shamil:没有提供默认值,插入语句指定了显式的 NULL 值。仅在未完全指定列或使用关键字 DEFAULT 时才适用于使用默认值。 - user330315
1
请阅读此链接:https://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_explicit_defaults_for_timestamp,它可能会有所帮助。这是关于`explicit_defaults_for_timestamp`系统变量的描述,它在5.6中被添加。 - krokodilko
显示剩余7条评论
2个回答

12
在5.5版本中你展示的行为实际上是一个错误,这个错误已在5.6.11中得到修复。请查看底部的5.6.11版本说明。此问题是bugs 68472和16394472的一部分(我无法找到后者的链接)。
如果关闭explicit_defaults_for_timestamp标志,它应该像在5.5中一样正常工作。
这正是我们从5.5升级到5.6时遇到的相同问题。

这个原因有点复杂。由于一个错误,你在5.5版本中的查询可以将某一列设置为NULL,而实际上你本不应该这样做。当5.6版本推出时,他们引入了explicit_defaults_for_timestamp标志,以允许弃用的功能在过渡期间继续工作。然而,在5.6.11版本中,他们修复了你(和我的)查询所依赖的错误。幸运的是,如果关闭该标志,新的默认行为恰好是我们想要的行为。 - Boerema

0

你尝试过省略这一列吗?

INSERT INTO `test` () VALUES ();

嗨,罗布,这对我的示例有效,但在生产中,我们使用Hibernate作为我们的ORM,因此希望能够在许多情况下设置NULL列,无论如何感谢。 - BombTodley
将默认值设置为动态时间戳而不是实际的空值,这是否可能呢?嗯,不确定。将 "explicit_defaults_for_timestamp" 设置为 OFF 是否能实现这一点? - Rob Starling
没错 - 正如我在上面的评论中所说,这对我来说仍然没有意义,但它能用! - BombTodley
1
我在我的答案评论中也说过,这个方法能够起作用的原因有点复杂。由于一个错误,你在5.5版本中可以将列设置为NULL,而实际上你本不应该这样做。当5.6版本推出时,他们引入了explicit_defaults_for_timestamp标志,以允许弃用的功能在过渡期间继续工作。然而,在5.6.11中,他们修复了你(和我)查询所依赖的错误。幸运的是,如果关闭该标志,新的默认行为恰好是我们想要的行为。 - Boerema

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接