我正在运行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文档中的第二个引用,任何人都可以让我知道它为什么会出现这个错误?
答案 0 :(得分:157)
错误是由于sql模式,根据最新的MYSQL 5.7文档可以是严格模式
严格模式会影响服务器是否允许'作为有效日期: 如果未启用严格模式,' 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配置文件中或通过命令
按命令
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_TABLES
或STRICT_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进行更全面的审核:
答案 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来重新创建问题。
如果它适用于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)
答案 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