导入数据库时报错1067 – Invalid default value for ‘field’

2022-12-15 14:58:21 浏览数 (1)

最近在优化yii主题时,修改了一个yii主题中新增的数据库字段名称,在更新数据库时,mysql报了1067-Invalid default value for 'comment_date'这样的错误,当时执行的是下面这条语句:

代码语言:javascript复制
ALTER TABLE wp_comments CHANGE COLUMN old_col_name new_col_name TINYINT NOT NULL DEFAULT 0;

MySQL给的错误提示很清楚,comment_date这个字段的默认值是无效的,这个问题有些令我不解(我的疑问:WordPress能建表成功,为什么会出现默认值无效的情况呢),后来突然想起我在yii主题成形的时候,对运行环境进行过一次升级,PHP从5.6升级到了7.2,Apache从2.2升级到了2.4,MySQL从5.6升级到了5.7,会不会是因为MySQL升级导致的呢(因为MySQL的升级没有进行数据的重新导入,而是沿用了5.6的数据文件)。

如果是MySQL升级导致的问题,那么是什么原因呢,错误报告的是默认值无效,也就是说默认值是被限制的,那么先检查一下表结构:

代码语言:javascript复制
mysql> DESC wp_comments;
 ---------------------- --------------------- ------ ----- --------------------- ---------------- 
| Field                | Type                | Null | Key | Default | Extra          |
 ---------------------- --------------------- ------ ----- --------------------- ---------------- 
| comment_ID           | bigint(20) unsigned | NO   | PRI | NULL | auto_increment |
| comment_post_ID      | bigint(20) unsigned | NO   | MUL | 0 |                |
| comment_author       | tinytext            | NO   |     | NULL |                |
| comment_author_email | varchar(100)        | NO   | MUL |  |                |
| comment_author_url   | varchar(200)        | NO   |     |  |                |
| comment_author_IP    | varchar(100)        | NO   |     |  |                |
| comment_date         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| comment_date_gmt     | datetime            | NO   | MUL | 0000-00-00 00:00:00 |                |
| comment_content      | text                | NO   |     | NULL |                |
| comment_karma        | int(11)             | NO   |     | 0 |                |
| comment_approved     | varchar(20)         | NO   | MUL | 1 |                |
| comment_agent        | varchar(255)        | NO   |     |  |                |
| comment_type         | varchar(20)         | NO   |     |  |                |
| comment_parent       | bigint(20) unsigned | NO   | MUL | 0 |                |
| user_id              | bigint(20) unsigned | NO   |     | 0 |                |
| comment_reply_notify | tinyint(4)          | NO   |     | 0 |                |
 ---------------------- --------------------- ------ ----- --------------------- ---------------- 
16 rows in set (0.00 sec)

或者也可以分步查看comment_date字段的字段类型和默认值。

默认值:

代码语言:javascript复制
mysql> SELECT DEFAULT(comment_date) AS default_comment_date FROM `wp_comments` L
IMIT 1;
 ---------------------- 
| default_comment_date |
 ---------------------- 
| 0000-00-00 00:00:00  |
 ---------------------- 
1 row in set (0.00 sec)

字段类型:

代码语言:javascript复制
mysql> SELECT data_type FROM information_schema.columns WHERE table_name='wp_comments' AND column_name='comment_date';
 ----------- 
| data_type |
 ----------- 
| datetime  |
 ----------- 
1 row in set (0.01 sec)

从上面的查询结果我们可以看到comment_date默认值是0000-00-00 00:00:00,数据类型是datetime,在时间格式使用这种默认值是很常见的,在5.7下难道不兼容??

再看看MySQL的sql_mode

代码语言:javascript复制
mysql> show variables like 'sql_mode';
 --------------- ------------------------------------------------------------------------------------------------------------------------------------------- 
| Variable_name | Value |
 --------------- ------------------------------------------------------------------------------------------------------------------------------------------- 
| 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 |
 --------------- ------------------------------------------------------------------------------------------------------------------------------------------- 
1 row in set, 1 warning (0.01 sec)

果然sql_mode中有两个选项(NO_ZERO_IN_DATE,NO_ZERO_DATE),显示date类型的字段默认值不能为0,而我们的默认值正好就是0,终于找到问题所在!!!

解决方案:

临时方案:

将NO_ZERO_IN_DATE,NO_ZERO_DATE这两个选项从sql_mode中暂时移除。

代码语言:javascript复制
mysql> SET SESSION sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected, 1 warning (0.00 sec)

永久方案:

Windows用户修改my.ini,Linux用户修改my.cnf。

在mysqld添加如下信息:

代码语言:javascript复制
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

本文采用 「CC BY-NC-SA 4.0」创作共享协议,转载请标注以下信息:

原文出处:Yiiven https://cloud.tencent.com/developer/article/2193230

0 人点赞