最近在學習《MySQL技術內幕:SQL編程》并做了筆記,本博客是一篇筆記類型博客,分享出來,方便自己以后復習,也可以幫助其他人
SQL_MODE:MySQL特有的一個屬性,用途很廣,可以通過設置屬性來實現某些功能支持
# 全局的SQL_MODE
SELECT @@global.sql_mode;
# 當前會話的SQL_MODE
SELECT @@session.sql_mode;
SQL_Mode默認值是為空的,對于SQL_mode的設置可以在mysql配置文件(my.ini或者my.cnf),或者直接通過命令設置
嚴格模式:是指將sql_mode設置為STRICT_TRANS_TABLES或者STRICT_ALL_TABLES,設置為嚴格模式是不允許非法的操作的,比如將Null值寫到非空要求的字段里,或者寫入不合法的日期數據,比如'2019-09-40'
SET GLOBAL sql_mode ='STRICT_TRANS_TABLES';
SET GLOBAL sql_mode ='STRICT_ALL_TABLES';
數據原本有數據的情況,就不要直接set,用concat連接起來:
set @@session.sql_mode=concat(@@sql_mode,',IGNORE_SPACE');
- STRICT_TRANS_TABLES:啟用了嚴格模式,只影響事務表,不影響非事務表,如果一個值不能寫到事務表(例如存儲引擎為InnoDB),就中斷當前操作不影響非事務表(例如存儲引擎為MYISAM)
- STRICT_ALL_TABLES:啟用STRICT_ALL_TABLES后,對所有引擎的表都啟用嚴格模式
- ANSI_QUOTES:啟用ANSI_QUOTES后,不能用雙引號來引用字符串,因為開啟這個模式后,雙引號被解釋為識別符
- ALLOW_INVALID_DATES:這個模式啟用后,將開啟對日期的不完全檢驗,比如只檢驗月份是否在112,日期是否在131,這種檢驗對于date、datetime類型的是可以的,但是對于timestamp是沒效果的
- ERROR_FOR_DIVISION_BY_ZERO:在insert或者update過程中,如果數據除以0(或者MOD(
x,0))會產生錯誤,如果沒開啟改模式,則數據除以0時,MySQL返回NULL值 - HIGH_NOT_PRECEDENCE NOT:開啟舊版本的表達式優先級,例如 Not a between b and c被解釋為not (a between b and c),不過在MySQL的一些舊版本里是解釋為(not a) between b and c的,如果要使用舊版本的這種,就要開啟 HIGH_NOT_PRECEDENCE NOT
- IGNORE_SPACE:忽略函數名和括號之間的空格,這個屬性默認是不開啟的,一般是不建議開啟的,比如某些特殊情況才可以開啟,比如 select count (1) from t; count之間有空格會報錯,開啟后就不會報錯,不過一般是不會在函數和括號直接加空格的,除非有表名或者列名也命名為count,這種情況就要加空格,表名,這個count不是表名,而是函數名
- NO_AUTO_CREATE_USER:禁止GRANT創建密碼為空的用戶
- NO_AUTO_VALUE_ON_ZERO:這個屬性是設置對于自動增長的列不允許寫0值,也寫入了0或者null,不會寫0,假如寫入了0,數據表里本來沒數據,就會寫1,以此類推
- NO_BACKSLASH_ESCAPES:反斜桿“\”作為普通字符而非轉義符
- NO_DIR_IN_CREATE:在創建表時忽略所有INDEX DIRECTORY和DATE DIRECTORY的選項
- NO_ENGINE_SUBTRACTION:用到的存儲引擎被禁用或者未編譯,就用默認的存儲引擎,并且拋出異常,
- NO_UNSIGNED_SUBTRACTION:啟用這個屬性后,兩個unsigned類型相減返回signed類型
- NO_ZERO_DATE:不允許寫入為0格式的日期,比如“0000-00-00 00:00:00”,啟用這個屬性后,寫入這種類型數據就會拋異常
- NO_ZERO_IN_DATE:在嚴格模式下,不允許日期和月份為零的情況
- ONLY_FULL_GROUP_BY:如果select出現的列沒有在group by中就會報錯
- PAD_CHAR_TO_FULL_LENGTH:對于char類型字段,查詢時候不要截取空洞數據,所謂空洞數據就是自動填充0x20的數據
CREATE TABLE t (a CHAR(10));
INSERT INTO t SELECT 'a';
在這里插入圖片描述
在默認情況下查詢是這樣的,如果設置PAD_CHAR_TO_FULL_LENGTH,查詢出來的是:
在這里插入圖片描述
- REAL_AS_FLOAT:將REAL作為FLOAT的同義詞,而不是double的同義詞
- PIPES_AS_CONCAT:將“||”視為字符串的連接操作符,而非或運算符,這個就和oracle是一樣的
下面給出幾種選項的組合:
- ANSI:等同于RELA_AS_FLOAT、PIPES_AS_CONCAT和ANSI_QUOTES、IGNORE_SPACE的組合
- ORACLE:等同于PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NO_TABLE_OPTIONS、NO_FIELD_OPTIONS和NO_AUTO_CREATE_USER的組合
- TRADITIONAL:等同于STRICT_TRANS_TABLES、STRICT_ALL_TABLES、NO_ZERO_IN_DATE、NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO、NO_AUTO_CREATE_USER、NO_ENGINE_SUBSTITUTION的組合
- MSSQL:等同于PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NO_TABLE_OPTIONS和NO_FIELD_OPTIONS的組合
- DB2:等同于PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NO_TABLE_OPTIONS和NO_FIELD_OPTIONS的組合
- MYSQL323:等同于NO_FIELD_OPTIONS和HIGH_NOT_PRECEDENCE的組合
- MYSQL40:等同于NO_FIELD_OPTIONS和HIGH_NOT_PRECEDENCE的組合
- MAXDB:等同于PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NO_TABLE_OPTIONS、NO_FIELD_OPTIONS和NO_AUTO_CREATE_USER的組合