MySQL中设置日期或日期时间的默认值时出错

MySQL中设置日期或日期时间的默认值时出错,mysql,sql,date,datetime,console,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' 只起作用 日期也一样 作为旁注,在以下文件中提到: 日期类

我正在运行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'
只起作用

日期也一样

作为旁注,在以下文件中提到:

日期类型用于包含日期部分但不包含时间部分的值。MySQL以“YYYY-MM-DD”格式检索并显示日期值。支持的范围为“1000-01-01”到“9999-12-31”

即使他们也会说:

无效的日期、日期时间或时间戳值被转换为相应类型的“零”值(“0000-00-00”或“0000-00-00 00:00”)

考虑到MySQL文档中的第二句话,有人能告诉我为什么会出现这样的错误吗

它适用于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)
您可以创建SQLFIDLE来重新创建问题


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

错误是因为sql模式,根据最新的MYSQL 5.7文档,sql模式可能是严格模式

:

严格模式影响服务器是否允许“0000-00-00”作为有效日期: 如果未启用严格模式,则允许使用“0000-00-00”,并且插入不会产生警告。 如果启用了严格模式,则不允许使用“0000-00-00”,并且插入会产生错误,除非也给出了忽略。对于插入忽略和更新忽略,允许使用“0000-00-00”,并且插入会产生警告

检查MYSQL模式

选择@GLOBAL.sql\u模式全局、@SESSION.sql\u模式会话

禁用严格传输表模式

但是,要允许格式
0000-00-00 00:00:00
必须在mysql配置文件中或通过命令禁用STRICT_TRANS_TABLES模式

通过命令

SET sql\u mode=''

设置全局sql\u模式=“”

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

如果上述方法不起作用,请转到
/etc/mysql/my.cnf
(根据ubuntu)并注释掉
STRICT\u TRANS\u TABLES

此外,如果要在服务器启动时永久设置sql模式,则在Linux或MacOS上的
my.cnf
中包含
set sql\u mode='
。对于windows,这必须在
my.ini
文件中完成

注意

但是,MYSQL 5.6默认情况下未启用严格模式。因此,它不会产生如下所示的错误:

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

更新

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

我不认为这是一个错误,因为MYSQL是随着时间的推移而演变的,在产品进一步改进的基础上,有些东西发生了变化

但是,我有另一个关于
NOW()
函数的相关错误报告

另一个有用的注释[参见]

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

关于无零日期的更新


从MySQL到5.7.4,此模式已被弃用。对于以前的版本,必须注释掉配置文件中的相应行。参考

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

并重新启动所有服务

这将禁用严格模式。根据文件,“严格模式”是指启用了一个或两个
strict\u TRANS\u表
strict\u ALL\u表
的模式。 报告说:

“MySQL 5.7中的默认SQL模式包括以下模式: 只有完整的分组依据,严格的转换表,没有零的输入日期, 无日期、错误、自动创建用户,以及 没有引擎替换。”


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

在“首选项”面板中将SQL_模式删除为传统模式

配置语法问题 在*nix系统下的某些MYSQL版本(测试版本为5.7.*)上,您应该使用以下语法:

[mysqld]

sql-mode="NO_BACKSLASH_ESCAPES,STRICT_TRANS_TABLE,NO_ENGINE_SUBSTITUTION"
这些不起作用: 破折号无引号

下划线不加引号

下划线和引号

对配置值和sql模式的更全面的回顾:


此答案仅适用于MySQL 5.7:

Best并不是在sql_模式下设置为空,而是在PHP中使用一个会话变量,该变量包含:

SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
因此,至少您保留了其他默认值

mysql文档不清晰是很疯狂的,您需要在sql_模式下删除这些默认值:

没有零零年的日期,没有零零年的日期,我理解,但在未来的版本中,这将被停止

在参数被忽略之前,严格检查所有检查表,因此您也需要删除它

最后也是传统的,但文档中提到了这个参数:“在向列中插入不正确的值时,给出一个错误而不是警告”,有了这个参数,没有插入零值的日期,但没有“是”


MySQL并不是用这些参数和组合来组织的。
MySQL版本14.14发行版5.7.18的选项组合,用于Linu
sql-mode=NO_ENGINE_SUBSTITUTION
sql_mode=NO_ENGINE_SUBSTITUTION
sql_mode="NO_ENGINE_SUBSTITUTION"
SET SESSION sql_mode= 'ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
SELECT @@SESSION.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';
SELECT @@GLOBAL.sql_mode;
SET GLOBAL sql_mode = '...';
 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<'0000-01-01'
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';
"sql_mode=NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE"

REMOVE "NO_ZERO_IN_DATE"
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'");
SELECT @@GLOBAL.sql_mode global, @@SESSION.sql_mode session