1.Mysql5.7-sql_mode
MySQL 5.6以后timestamp設定默認值規則改變,不能為”0000 00-00 00:00:00”,一般安裝的5.7版本的sql_mode(系統變量)配置為嚴格模式,在嚴格模式下將控制我們在sql腳本的值限制。
2.常見異常:
--執行語句:
CREATE TABLE IF NOT EXISTS `Goods` ( `goods_Id` INT NOT NULL COMMENT '商品Id', `goods_Name` VARCHAR(30) COMMENT '商品名稱', `goods_CardNo` VARCHAR(50) COMMENT '商品編碼', `goods_Price` DOUBLE DEFAULT NULL COMMENT '商品進價', `shopp_Price` DOUBLE DEFAULT NULL COMMENT '商品售價', `goods_CreateTime` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '進貨時間', `goods_lastupdateTime` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP COMMENT'最后更新時間', PRIMARY KEY (`goods_Id`), KEY `CarId` (`goods_Id`) USING BTREE, `Cat_Id` INT COMMENT '商品類型', `goods_Number` INT COMMENT '商品數量' )ENGINE=InnoDB DEFAULT CHARSET=utf8;
--報錯:
Invalid default value for 'goods_lastupdateTime'
3.解決方案
--查詢mysql下當前的sql_mode系統變量配置詳情,刪除對應配置:NO_ZERO_IN_DATE,NO_ZERO_DATE
①此種配置方式只對當前會話狀態下有效,重啟MySQL服務后配置失效,退回到原來配置
-- mysql控制台下:
mysql>show session variable '%sql_mode%'; mysql>set sql_mode= "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
-- Navicat下:

②配置永久有效,在MySQL配置文件下添加配置,window下為my.ini,Liunx下為my.cnf
sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

-- 重新啟動MySQL服務生效
[~] systemctl restart mysqld
4.timestamp屬性之:CURRENT_TIMESTAMP與ON UPDATE CURRENT_TIMESTAMP詳解
①CURRENT_TIMESTAMP屬性說明:當向數據表執行 insert操作時,如果有個 timestamp字段屬性設為 CURRENT_TIMESTAMP,則無論這個字段有沒有set值都插入當前系統時間。
②ON UPDATE CURRENT_TIMESTAMP屬性說明:當timestamp字段屬性配置ON UPDATE CURRENT_TIMESTAMP時,在后續數據表中數據發生Update操作將自動更新執行時間。
③測試:
CREATE TABLE IF NOT EXISTS `t_map`( `Id` INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '自增主鍵Id', `Name` VARCHAR(20) DEFAULT '', -- '在執行insert語句后此字段記錄為當前系統時間且后續不受update操作影響而自動更新' `Time_1` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , -- '執行insert操作,此字段不賦值默認為0000-00-00 00:00:00且不受update操作影響而更新,如有報錯,按以上方式處理' `Time_2` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', -- '在執行insert操作后,此字段記錄當前系統時間,當執行Update操作,此字段更新為最新系統update操作時間' `Time_3` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP , -- '在執行insert操作,此字段不賦值默認為0000-00-00 00:00:00且受后續update操作影響更新為操作最新時間' `Time_4` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP )ENGINE=InnoDB DEFAULT CHARSET=utf8;
--執行insert插入語句
INSERT INTO t_map(`Name`) VALUES('a'),('b'),('c'),('d');

--執行Update操作
-- 更新Id=1的值,可以看到Time_3、Time_4已經更新為當前系統最新時間 UPDATE t_map SET `Name`='aa' WHERE Id=1;

5.sql_mode系統變量值說明
1.ONLY_FULL_GROUP_BY:
對於GROUP BY聚合操作,如果在SELECT中的列,沒有在GROUP BY中出現,那么這個SQL是不合法的,因為列不在GROUP BY從句中。
2.NO_AUTO_VALUE_ON_ZERO:
該值影響自增長列的插入。默認設置下,插入0或NULL代表生成下一個自增長值。如果用戶 希望插入的值為0,而該列又是自增長的,那么這個選項就有用了。
3.STRICT_TRANS_TABLES:
在該模式下,如果一個值不能插入到一個事務表中,則中斷當前的操作,對非事務表不做限制。
4.NO_ZERO_IN_DATE:
在嚴格模式下,不允許日期和月份為零。
5.NO_ZERO_DATE:
設置該值,mysql數據庫不允許插入零日期,插入零日期會拋出錯誤而不是警告。
6.ERROR_FOR_DIVISION_BY_ZERO:
在INSERT或UPDATE過程中,如果數據被零除,則產生錯誤而非警告。如 果未給出該模式,那么數據被零除時MySQL返回NULL。
7.NO_AUTO_CREATE_USER:
禁止GRANT創建密碼為空的用戶。
8.NO_ENGINE_SUBSTITUTION:
如果需要的存儲引擎被禁用或未編譯,那么拋出錯誤。不設置此值時,用默認的存儲引擎替代,並拋出一個異常。
9.PIPES_AS_CONCAT:
將"||"視為字符串的連接操作符而非或運算符,這和Oracle數據庫是一樣的,也和字符串的拼接函數Concat相類似。
10.ANSI_QUOTES:
啟用ANSI_QUOTES后,不能用雙引號來引用字符串,因為它被解釋為識別符。
注:ORACLE的sql_mode設置等同:PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER.
6.參考文獻
①https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html
②https://www.cnblogs.com/jiliunyongjin/p/7569893.html
③https://www.cnblogs.com/wenxin1120/p/11234990.html
