MySQL中设置日期或日期时间的默认值时出错
我正在运行MySql Server 5.7.11,下面这句话: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' 只起作用 日期也一样 作为旁注,在以下文件中提到: 日期类
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