在为DATE或DATETIME设置默认值时在mysql中出错

我正在运行MySql Server 5.7.11和这句话:

updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00' 

工作。 给出错误:

 ERROR 1067 (42000): Invalid default value for 'updated' 

但以下几点:

 updated datetime NOT NULL DEFAULT '1000-01-01 00:00:00' 

只是工作

DATE的情况相同。

作为旁注 ,它在mysql文档中提到:

DATEtypes用于具有date部分但不包含时间部分的值。 MySQL以'YYYY-MM-DD'格式检索并显示DATE值。 支持的范围是“1000-01-01”到“9999-12-31”。

即使他们也说:

无效的DATE,DATETIME或TIMESTAMP值将转换为相应types(“0000-00-00”或“0000-00-00 00:00:00”)的“零”值。

考虑到mysql文档的第二个引用,谁能让我知道为什么它给出了这个错误?

错误是因为sql模式可能是严格的模式按照最新的MYSQL 5.7文档

MySQL文档5.7说 :

严格模式会影响服务器是否允许“0000-00-00”作为有效date:如果未启用严格模式,则允许“0000-00-00”,并且插入不会产生警告。 如果启用严格模式,则不允许使用“0000-00-00”,除非给出IGNORE,否则插入会产生错误。 对于INSERT IGNORE和UPDATE IGNORE,“0000-00-00”是允许的,插入会产生警告。

检查MYSQL模式

SELECT @@GLOBAL.sql_mode global, @@SESSION.sql_mode session

禁用STRICT_TRANS_TABLES模式

但是,要允许格式为“ 0000-00-00 00:00:00 ,则必须在mysqlconfiguration文件或命令中禁用STRICT_TRANS_TABLES模式

通过命令

SET sql_mode = '';

要么

SET GLOBAL sql_mode = '';

使用关键字GLOBAL需要超级previliges,它会影响所有客户端从那时起连接的操作

如果上面的不工作比去/etc/mysql/my.cnf (根据Ubuntu的)和注释掉STRICT_TRANS_TABLES

另外,如果你想在服务器启动时永久设置sql模式,那么在Linux或MacOS上的my.cnf包含SET sql_mode='' 。 对于windows,这个必须在my.ini文件中完成。

注意

但是MYSQL 5.6默认情况下严格模式是不启用的。 因此,它不会产生错误,根据MYSQL 6文档说

MySQL允许您将“0000-00-00”的“零”值存储为“虚拟date”。这在某些情况下比使用NULL值更方便,并且使用更less的数据和索引空间。 要禁止“0000-00-00”,请启用NO_ZERO_DATE SQL模式。

UPDATE

关于@Dylan-Su所说的错误问题:

我不认为这是MYSQL随着时间的推移发展而来的错误,因为有些东西是根据产品的进一步改进而改变的。

不过,我有另一个有关NOW()函数的相关错误报告

date时间字段不接受默认NOW()

另一个有用的注意事项 [请参阅自动初始化和更新TIMESTAMP和DATETIME ]

从MySQL 5.6.5开始,TIMESTAMP和DATETIME列可以自动初始化并更新为当前date和时间(即当前时间戳)。 在5.6.5之前,这仅适用于TIMESTAMP,每个表最多只有一个TIMESTAMP列。 以下注释首先描述了MySQL 5.6.5及更高版本的自动初始化和更新,然后介绍了5.6.5之前版本的差异。

关于NO_ZERO_DATE的更新

从5.7.4开始,MySQL不推荐使用这种模式。 对于以前的版本,您必须在configuration文件中注释掉相应的行。 请参阅NO_ZERO_DATE上的MySQL 5.7文档

WAMP 3.0.6与MySql 5.7.14我有这个错误。

解答

c:\wamp\bin\mysql\mysql5.7.14\my.ini文件中更改第70行(如果您的ini文件未触及)

 sql-mode= "STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER" 

 sql-mode="ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE,NO_ZERO_IN_DATE,NO_AUTO_CREATE_USER" 

并重新启动所有服务。

这将禁用严格模式。 根据文档,“严格模式”是指启用了STRICT_TRANS_TABLESSTRICT_ALL_TABLES一个或两个的模式。 该文件说:

“MySQL 5.7中的默认SQL模式包括以下模式:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER和NO_ENGINE_SUBSTITUTION。

configuration语法问题

在* nix系统下的某些版本的MYSQL(testing5.7。*)中,应该使用以下语法:

 [mysqld] sql-mode="NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLE,NO_ENGINE_SUBSTITUTION" 

这些将不起作用:

没有引号

 sql-mode=NO_ENGINE_SUBSTITUTION 

下划线没有引号

 sql_mode=NO_ENGINE_SUBSTITUTION 

下划线和引号

 sql_mode="NO_ENGINE_SUBSTITUTION" 

configuration值和sql-mode的更全面的回顾:

如何设置永久的Sql模式标志

它适用于5.7.8:

 mysql> create table t1(updated datetime NOT NULL DEFAULT '0000-00-00 00:00:00'); Query OK, 0 rows affected (0.01 sec) mysql> show create table t1; +-------+-------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+-------------------------------------------------------------------------------------------------------------------------+ | t1 | CREATE TABLE `t1` ( `updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 | +-------+-------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) mysql> select version(); +-----------+ | version() | +-----------+ | 5.7.8-rc | +-----------+ 1 row in set (0.00 sec) 

您可以创build一个SQLFiddle来重新创build您的问题。

http://sqlfiddle.com/

如果它适用于MySQL 5.6和5.7.8,但在5.7.11上失败。 那么它可能是一个5.7.11的回归bug。

这个答案只适用于MySQL 5.7:

最好不是真的在空白的sql_mode中设置,而是在php中使用一个会话variables:

 SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' 

所以至less你保留了另一个默认值

mysql文档不清楚,这是疯狂的,你需要在sql_mode中删除这个转义值:

NO_ZERO_IN_DATE,NO_ZERO_DATE,据我所知,但在未来的版本中,这将被停用。

STRICT_ALL_TABLES,在这之前,参数将被忽略,所以你也需要删除它。

最后也是TRADITIONAL,但是文档中提到了这个参数:“当给列插入一个不正确的值时给出一个错误而不是一个警告”,用这个参数,没有插入零值的date,但是没有

mysql并不是真的用这些参数和组合来组织的。

解决MySQL Workbench的问题(在服务器端应用解决scheme之后):

在首选项面板中将SQL_MODE移除到TRADITIONAL。

在这里输入图像说明

适用于mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64)选项组合mysql Ver 14.14 Distrib 5.7.18, for Linux (x86_64)

不扔:

STRICT_TRANS_TABLES + NO_ZERO_DATE

抛出:

STRICT_TRANS_TABLES + NO_ZERO_IN_DATE

我在Ubuntu的/etc/mysql/my.cnf设置:

 [mysqld] sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" 

首先select当前会话sql_mode

 SELECT @@SESSION.sql_mode; 

那么你会得到这样的默认值 :

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

然后在没有'NO_ZERO_DATE'情况下设置sql_mode

 SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'; 

如果您有资助,您也可以为GLOBAL

 SELECT @@GLOBAL.sql_mode; SET GLOBAL sql_mode = '...';