为DATE或DATETIME设置默认值时,MySQL错误


124

我正在运行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文档中有所提及:

DATE类型用于具有日期部分但没有时间部分的值。MySQL检索并以“ YYYY-MM-DD”格式显示DATE值。支持的范围是“ 1000-01-01”至“ 9999-12-31”。

即使他们也说:

无效的DATE,DATETIME或TIMESTAMP值将转换为适当类型(“ 0000-00-00”或“ 0000-00-00 00:00:00”)的“零”值。

还考虑了MySQL文档中的第二个引号,有人可以让我知道为什么会出现该错误吗?


11
为什么要一个显然毫无意义的默认值?如果日期未知,那么这正是NULL目的。
Tom H

注意:这在SQL Fiddle的5.6版中有效-sqlfiddle.com/#!9/02c98
Gordon Linoff

@Karlos检查更新的答案。
geeksal 2016年

Answers:


209

错误是由于sql模式所致,根据最新的MYSQL 5.7文档,sql模式可以是严格模式

MySQL文档5.7说

严格模式影响服务器是否允许将“ 0000-00-00”作为有效日期:如果未启用严格模式,则允许“ 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您必须在mysql配置文件中或通过命令禁用STRICT_TRANS_TABLES模式

通过命令

SET sql_mode = '';

要么

SET GLOBAL sql_mode = '';

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

如果上述方法不起作用,则转到/etc/mysql/my.cnf(按照ubuntu)并注释掉STRICT_TRANS_TABLES

另外,如果你想永久设置在服务器启动时的SQL模式,然后包括SET sql_mode=''my.cnfLinux或MacOS的。对于Windows,必须在my.ini文件中完成。

注意

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

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

更新

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

我不认为这是MYSQL随时间演变的错误,因为随着产品的进一步改进而发生了一些变化。

但是我还有另一个有关该NOW()功能的错误报告

日期时间字段不接受默认的NOW()

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

从MySQL 5.6.5开始,TIMESTAMP和DATETIME列可以自动初始化并更新为当前日期和时间(即当前时间戳)。在5.6.5之前,这仅适用于TIMESTAMP,并且每个表最多包含一个TIMESTAMP列。以下说明首先介绍了MySQL 5.6.5及更高版本的自动初始化和更新,然后介绍了5.6.5之前版本的区别。

关于NO_ZERO_DATE的更新

从5.7.4版本的MySQL开始,不建议使用此模式。对于以前的版本,您必须注释掉配置文件中的相应行。请参阅NO_ZERO_DATE的MySQL 5.7文档


5
UPDATE忽视的是什么,我一直在寻找👍🏻
Afanasii库拉

2
错误。我有STRICT_TRANS_TABLES我的MySQL的两种情况下,本地和服务器。但是,我可以轻松地0000-00-00在本地实例中插入,但不能在服务器实例中插入-引发错误。为什么?因为我的服务器MySQL配置已NO_ZERO_DATE启用。而且我的本地人没有。
格林

好的@Green我会找出答案并更新答案(如果适用)
geeksal

4
在我的情况下,“ SET sql_mode =“”“不起作用。'SET GLOBAL sql_mode =“”;' 为我做了工作。
arjen Stens

NO_ZERO_DATE应删除
Preshan Pradeepa,

18

使用MySql 5.7.14的WAMP 3.0.6出现此错误。

解决方案

变线70(如果你的ini文件是不变)在 c:\wamp\bin\mysql\mysql5.7.14\my.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。


14

我遇到了一种情况,其中数据混合在NULL和Registry的日期字段之间。但是我不知道如何将'0000-00-00'更新为NULL,因为

 update my_table set my_date_field=NULL where my_date_field='0000-00-00'

不再允许。我的解决方法非常简单:

update my_table set my_date_field=NULL where my_date_field<'1000-01-01'

因为所有不正确的 my_date_field值(无论是否正确的日期)都来自该日期之前。


2
完美的快速解决方案。实际上,您也可以使用,<'0000-01-01'因为它当然是有效日期。
里奇·麦克马斯特

5

配置语法问题

在* nix系统下的某些版本的MYSQL(经测试5.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"

有关配置值和sql-mode的更完整的评论:

如何设置永久Sql模式标志


5

首先选择当前会话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'

然后设置为sql_mode'NO_ZERO_DATE'

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 = '...';

4

只需添加以下行: sql_mode = "NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

内部文件: /etc/mysql/mysql.conf.d/mysqld.cnf

然后 sudo service mysql restart


1
适用于5.7.23。
user2513149

1
我可能SELECT @@SESSION.sql_mode;首先建议 ,他们从它给您的内容中删除NO_ZERO_IN_DATE,NO_ZERO_DATE和STRICT_TRANS_TABLES。这样,您可以保留已启用的任何其他设置。我为SQL模式设置的不仅仅是这两项。不知道它们都做什么,但是我现在不想冒险将它们删除。
Radley Sustaire,

2

它适用于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)

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

http://sqlfiddle.com/

如果它适用于MySQL 5.6和5.7.8,但在5.7.11上失败。然后可能是5.7.11的回归错误。


1

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

在首选项面板中,将SQL_MODE删除为TRADITIONAL。

在此处输入图片说明


1

这个答案仅适用于MySQL 5.7:

Best并不是真正将sql_mode设置为空白,而是在PHP中使用具有以下内容的会话变量:

SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

因此,至少您要保留另一个默认值。

疯狂的是,MySQL文档不清晰,您需要在sql_mode中删除此默认值:

我知道是NO_ZERO_IN_DATE,NO_ZERO_DATE,但是在以后的版本中,它将不再使用。

STRICT_ALL_TABLES,在此之前,将忽略参数,因此您也需要删除它。

最后也是TRADITIONAL,但是文档中谈到了该参数:“在将不正确的值插入到列中时,给出错误而不是警告”,使用此参数时,不会插入具有零值的日期,但是没有。

这些参数和组合实际上并不是MySQL的组织形式。


0

的选项组合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

我在/etc/mysql/my.cnfUbuntu上的设置:

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


0

在目录xamp / mysql / bin中打开“ my.ini”并更改行:Sql_node->

“ sql_mode = NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE”

删除“ NO_ZERO_IN_DATE”


欢迎使用stackoverflow,请使用正确的代码格式以提高答案的可读性。
vlizana
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.