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