mysql5.7和mysql5.6默認的sql_mode說明

一.場景:

最近在部署新的項目,開發要求把原先舊項目的MySQL數據導入到新項目MySQL5.7的數據庫上。(舊項目上運行的是mysql5.6)
不就是導入數據嘛,也沒多想,那就導入唄。導入時,開始報錯了,
報錯如下:
MySQL 5.7 ERROR 1067 (42000): Invalid default value for 'CREATE_TIME'
MySQL 5.7 ERROR 1067 (42000): Invalid default value for 'day'
簡單google了下,發現原來是mysql5.6和mysql5.7默認的sql_mode模式參數是不一樣的,才導致的報錯。
下面咱們就簡單測試下,記錄下問題的解決過程:

二.演示過程:

2.1建測試表
首先創建一個表,表中包含一個字段day,允許插入零日期 '0000-00-00' COMMENT '日期',

CREATE TABLE `zx_scores` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `titles` char(15) NOT NULL,
  `icon` smallint(6) unsigned DEFAULT '0',
  `integral` int(10) NOT NULL DEFAULT '0',
  `isdefault` tinyint(1) unsigned NOT NULL DEFAULT '0',
`create_time` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`day` date NOT NULL DEFAULT '0000-00-00' COMMENT '日期',
  PRIMARY KEY (`id`),
  KEY `integral` (`integral`)
) ENGINE=Innodb AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

2.2登錄數據庫建表測試
登錄mysql5.6服務,查看默認的sql_mode爲:O_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
並且執行上面的建表語句,可以正常執行

於是又登錄MySQL5.7服務查看默認的sql_mode爲:

root@localhost [test01]> 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 (0.01 sec)
或者採用如下查看也是一樣的 :
select @@sql_mode; ##當前mysql的session會話層查看
select @@global.sql_mode;##全局查看

於是執行上面的建表語句,執行報錯了:

root@localhost [test01]>CREATE TABLE `zx_scores` (   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,   `titles` char(15) NOT NULL,   `icon` smallint(6) unsigned DEFAULT '0',   `integral` int(10) NOT 

NULL DEFAULT '0',   `isdefault` tinyint(1) unsigned NOT NULL DEFAULT '0', `create_time` varchar(20) COLLATE utf8_unicode_ci NOT NULL, `day` date NOT NULL DEFAULT '0000-00-00' COMMENT '日期',   

PRIMARY KEY (`id`),   KEY `integral` (`integral`) ) ENGINEE=Innodb AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
ERROR 1067 (42000): Invalid default value for 'day'

2.3報錯原因說明:

MySQL的sql_mode有兩種,一種是空值,一種是嚴格模式,會給出很多默認設置。在MySQL5.7之後默認使用嚴格模式。
NO_ZERO_DATE:若設置該值,MySQL數據庫不允許插入零日期,插入零日期會拋出錯誤而不是警告。
例如表中含字段TIMESTAMP列(如果未聲明爲NULL或顯示DEFAULT子句)將自動分配DEFAULT '0000-00-00 00:00:00'(零時間戳),也或者是本測試的表day列默認允許插入零日期 '0000-00-00' COMMENT '日期';這些顯然是不滿足sql_mode中的NO_ZERO_DATE而報錯。

2.4解決方式:
解決方式
方式一:先執行select @@sql_mode,複製查詢出來的值並將其中的NO_ZERO_IN_DATE,NO_ZERO_DATE刪除,然後執行set sql_mode = '修改後的值'。
此方法只在當前會話中生效
方式二:先執行select @@global.sql_mode,複製查詢出來的值並將其中的NO_ZERO_IN_DATE,NO_ZERO_DATE刪除,然後執行set global sql_mode = '修改後的值'。
此方法在當前服務中生效,重新MySQL服務後失效

方法三:在mysql的安裝目錄下,或my.cnf文件,新增 sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,
添加my.cnf如下:
[mysqld]
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

然後重啓mysql。
此方法永久生效.當然生產環境上是禁止重啓MySQL服務的,所以採用方式二來解決線上的問題。
寫此博文希望能夠幫助更多的遇到此問題的小夥伴們

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章