设置DATE或DATETIME的默认值时,mysql出错

时间:2016-04-02 14:11:46

标签: mysql sql date datetime console

我正在运行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 docs中提及:

  

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文档中的第二个引用,任何人都可以让我知道它为什么会出现这个错误?

14 个答案:

答案 0 :(得分:157)

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

MySQL Documentation 5.7 says

  

严格模式会影响服务器是否允许'作为有效日期:   如果未启用严格模式,' 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模式,请在Linux或MacOS上的SET sql_mode=''中包含my.cnf。对于Windows,这必须在my.ini文件中完成。

注意

但是,MYSQL 5.6中默认情况下不启用严格模式。因此,它不会产生MYSQL 6 documentation所说的

错误
  

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

<强>更新

关于@ Dylan-Su所说的错误事项:

我不认为这是MYSQL随着时间的推移而发展的错误,因为根据产品的进一步改进,一些事情会发生变化。

但是我有另一个关于NOW()功能

的相关错误报告

Datetime field does not accept default NOW()

另一个有用的说明 [请参阅Automatic Initialization and Updating for TIMESTAMP and 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不推荐使用此模式。对于以前的版本,您必须注释掉配置文件中的相应行。请参阅MySQL 5.7 documentation on NO_ZERO_DATE

答案 1 :(得分:14)

我使用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之一或两者的模式。 documentation说:

  

“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“。

答案 2 :(得分:4)

配置语法问题

在* 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进行更全面的审核:

How to setup permanent Sql Mode flags

答案 3 :(得分:4)

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

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

然后sudo service mysql restart

答案 4 :(得分:4)

我遇到了一种情况,其中数据混合在NULL和0000-00-00之间,用于日期字段。但是我不知道如何将'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值(无论是否正确的日期)都来自该日期之前。

答案 5 :(得分:3)

首先选择当前会话sql_mode

SELECT @@SESSION.sql_mode;

然后你会得到类似default value的东西:

  

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

答案 6 :(得分: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的回归错误。

答案 7 :(得分:1)

这个答案仅适用于MySQL 5.7:

最好不要将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,但是文档说的是这个参数:“在向列中插入不正确的值时给出错误而不是警告”,使用此参数,未插入带有零值的日期,但没有是。< / p>

使用这些参数和组合,MySQL并没有真正有条理。

答案 8 :(得分:0)

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

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

enter image description here

答案 9 :(得分: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

我在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"

答案 10 :(得分:0)

set global sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

答案 11 :(得分:0)

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

的Sql_node

“ sql_mode = NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE”

删除“ NO_ZERO_IN_DATE”

答案 12 :(得分:0)

我已经测试了如下修复:

1). On the file "system/library/db/mysqli.php" search and comment the line: 
"$this->connection->query("SET SESSION sql_mode = 'NO_ZERO_IN_DATE,NO_ZERO_DATE,NO_ENGINE_SUBSTITUTION'");"

2) Add the following line above the one you just commented:
// Correction by Added by A.benkorich
$this->connection->query("SET SESSION sql_mode = 'ONLY_FULL_GROUP_BY'");

答案 13 :(得分:0)

选择数据库并运行SQL查询:

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