昨晚在往MySQL資料庫中插入一組資料時,出錯了!資料庫無情了給我報了個錯誤:ERROR 1365(22012):Division by 0;意思是說:你不可以往資料庫中插入一個 除數為0的運算的結果。于是乎去谷歌了一番,總算是明白了其中的原因:是因為MySQL的sql_mode 模式限制着一些所謂的‘不合法'的操作。
解析
這個sql_mode,簡而言之就是:它定義了你MySQL應該支援的sql文法,對資料的校驗等等。。
如何檢視目前資料庫使用的sql_mode:
mysql> select @@sql_mode;
如下是我的資料庫目前的模式:
MySQL伺服器能夠工作在不同的SQL模式下,并能針對不同的用戶端以不同的方式應用這些模式。這樣,應用程式就能對伺服器操作進行量身定制以滿足自己的需求。這類模式定義了MySQL應支援的SQL文法,以及應該在資料上執行何種确認檢查。這樣,就能在衆多不同的環境下,與其他資料庫伺服器一起更容易地使用MySQL。從MySQL 4.1 開始,也能在啟動之後,使用SET[SESSION|GLOBAL]sql_mode='mode1,mode2…'語句,通過設定sql_mode變量更改模式。
sql_mode常用值
ONLY_FULL_GROUP_BY
對于GROUP BY聚合操作,如果在SELECT中的列、HAVING或者ORDER BY子句的列,沒有在GROUP BY中出現,那麼這個SQL是不合法的。
對于不合法的SQL語句,執行時會報如下錯誤
ERROR 1055 (42000): Expression #7 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'postscan.verifyDelayLog.auditor' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
NO_AUTO_VALUE_ON_ZERO
該值影響自增長列的插入。預設設定下,插入0或NULL代表生成下一個自增長值。如果使用者希望插入的值為0,該列又是自增長的,那麼這個選項就有用了。
STRICT_TRANS_TABLES
在該模式下,如果一個值不能插入到一個事物表中,則中斷目前的操作,對非事物表不做限制
NO_ZERO_IN_DATE
在嚴格模式,不接受月或日部分為0的日期。如果使用IGNORE選項,我們為類似的日期插入'0000-00-00'。在非嚴格模式,可以接受該日期,但會生成警告。
NO_ZERO_DATE
在嚴格模式,不要将 '0000-00-00'做為合法日期。你仍然可以用IGNORE選項插入零日期。在非嚴格模式,可以接受該日期,但會生成警告。
ERROR_FOR_DIVISION_BY_ZERO
在INSERT或UPDATE過程中,如果資料被零除,則産生錯誤而非警告。如 果未給出該模式,那麼資料被零除時MySQL傳回NULL
NO_AUTO_CREATE_USER
禁止GRANT建立密碼為空的使用者
NO_ENGINE_SUBSTITUTION
如果需要的存儲引擎被禁用或未編譯,那麼抛出錯誤。不設定此值時,用預設的存儲引擎替代,并抛出一個異常
PIPES_AS_CONCAT
将"||"視為字元串的連接配接操作符而非或運算符,這和Oracle資料庫是一樣的,也和字元串的拼接函數Concat相類似
ANSI_QUOTES
啟用ANSI_QUOTES後,不能用雙引号來引用字元串,因為它被解釋為識别符
MySQL5.0以上版本支援三種sql_mode模式:ANSI、TRADITIONAL和STRICT_TRANS_TABLES。
1、ANSI模式:寬松模式,更改文法和行為,使其更符合标準SQL。對插入資料進行校驗,如果不符合定義類型或長度,對資料類型調整或截斷儲存,報warning警告。對于本文開頭中提到的錯誤,可以先把sql_mode設定為ANSI模式,這樣便可以插入資料,而對于除數為0的結果的字段值,資料庫将會用NULL值代替。
2、TRADITIONAL模式:嚴格模式,當向mysql資料庫插入資料時,進行資料的嚴格校驗,保證錯誤資料不能插入,報error錯誤,而不僅僅是警告。用于事物時,會進行事物的復原。 注釋:一旦發現錯誤立即放棄INSERT/UPDATE。如果你使用非事務存儲引擎,這種方式不是你想要的,因為出現錯誤前進行的資料更改不會“滾動”,結果是更新“隻進行了一部分”。
3、STRICT_TRANS_TABLES模式:嚴格模式,進行資料的嚴格校驗,錯誤資料不能插入,報error錯誤。如果不能将給定的值插入到事務表中,則放棄該語句。對于非事務表,如果值出現在單行語句或多行語句的第1行,則放棄該語句。
設定 sql_mode
檢視目前連接配接會話的sql模式:
mysql> select @@session.sql_mode;
或者從環境變量裡取
mysql> show variables like "sql_mode";
檢視全局sql_mode設定:
mysql> select @@global.sql_mode;
設定global,需要重新連接配接進來才會生效
mysql> set global sql_mode='NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE';
設定全局sql_mode可以在不重新開機MySQL的情況下生效
配置檔案裡面設定
sql_mode=NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE
修改配置檔案後,重新開機MySQL服務生效
總結
以上就是這篇文章的全部内容了,希望本文的内容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支援。如果你想了解更多相關内容請檢視下面相關連結