1. 問題
用戶表中有一個created_by
非空字段蛙埂,表示是誰創(chuàng)建的這個用戶缺虐,因為系統(tǒng)默認有一個admin
用戶割坠,故在創(chuàng)建表語句中有一條插入語句
insert into user(id,username,password) values('1','admin',MD5('admin'));
經(jīng)過測試沒有問題抽诉,提交之后陨簇,同事找到我說sql腳本執(zhí)行報錯,一看錯誤日志是created_by
字段沒有默認值
[Err] 1364 - Field `created_by` doesn't have a default value
相同的SQL語句在不同的環(huán)境中執(zhí)行結(jié)果居然不一樣迹淌,經(jīng)過調(diào)查河绽,是兩個MySQL環(huán)境的sql_mode
不一樣導致的。
mysql> show variables like "sql_mode";
+---------------+--------------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------------+
| sql_mode | NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------+
sql_mode 問題: NOT NULL 列沒有默認值但代碼里也沒給值唉窃,在非嚴格模式下耙饰,int列默認為0
,string列默認為''
了纹份,所以沒有問題榔幸;但在嚴格模式下,是直接返回失敗的矮嫉。
2.查看與設置sql_mode
-- 查看當前連接會話的sql模式:
mysql> select @@session.sql_mode;
-- 或者從環(huán)境變量里取
mysql> show variables like "sql_mode";
-- 查看全局sql_mode設置:
mysql> select @@global.sql_mode;
-- 只設置global削咆,需要重新連接進來才會生效
-- 將sql_mode設置為嚴格模式
mysql> SET sql_mode='STRICT_TRANS_TABLES';
3. sql_mode常用值
官方手冊專門有一節(jié)介紹SQL Mode,SQL Mode 定義了兩個方面:MySQL應支持的SQL語法蠢笋,以及應該在數(shù)據(jù)上執(zhí)行何種確認檢查拨齐。
SQL_MODE常用值
- ONLY_FULL_GROUP_BY:
對于GROUP BY聚合操作,如果在SELECT中的列昨寞,沒有在GROUP BY中出現(xiàn)瞻惋,那么這個SQL是不合法的,因為列不在GROUP BY從句中
- NO_AUTO_VALUE_ON_ZERO:
該值影響自增長列的插入援岩。默認設置下歼狼,插入0或NULL代表生成下一個自增長值。如果用戶 希望插入的值為0享怀,而該列又是自增長的羽峰,那么這個選項就有用了。
- STRICT_TRANS_TABLES:
在該模式下添瓷,如果一個值不能插入到一個事務表中梅屉,則中斷當前的操作,對非事務表不做限制
- NO_ZERO_IN_DATE:
在嚴格模式下鳞贷,不允許日期和月份為零
- NO_ZERO_DATE:
設置該值坯汤,mysql數(shù)據(jù)庫不允許插入零日期,插入零日期會拋出錯誤而不是警告搀愧。
- ERROR_FOR_DIVISION_BY_ZERO:
在INSERT或UPDATE過程中惰聂,如果數(shù)據(jù)被零除,則產(chǎn)生錯誤而非警告咱筛。如 果未給出該模式搓幌,那么數(shù)據(jù)被零除時MySQL返回NULL
- NO_AUTO_CREATE_USER:
禁止GRANT創(chuàng)建密碼為空的用戶
- NO_ENGINE_SUBSTITUTION:
如果需要的存儲引擎被禁用或未編譯,那么拋出錯誤眷蚓。不設置此值時鼻种,用默認的存儲引擎替代,并拋出一個異常
PIPES_AS_CONCAT:
將"||"視為字符串的連接操作符而非或運算符沙热,這和Oracle數(shù)據(jù)庫是一樣的叉钥,也和字符串的拼接函數(shù)Concat相類似
ANSI_QUOTES:
無論何種mode,產(chǎn)生error之后就意味著單條sql執(zhí)行失敗篙贸,對于支持事務的表投队,則導致當前事務回滾;但如果沒有放在事務中執(zhí)行爵川,或者不支持事務的存儲引擎表敷鸦,則可能導致數(shù)據(jù)不一致。MySQL認為,相比直接報錯終止扒披,數(shù)據(jù)不一致問題更嚴重值依。于是 STRICT_TRANS_TABLES
對非事務表依然盡可能的讓寫入繼續(xù),比如給個”最合理”的默認值或截斷碟案。而對于 STRICT_ALL_TABLES
愿险,如果是單條更新,則不影響价说,但如果更新的是多條辆亏,第一條成功,后面失敗則會出現(xiàn)部分更新鳖目。
5.6.6 以后版本默認就是NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
扮叨,5.5默認為 ‘’ 。
參考: