透過MySQL的SQL_MODE參數可以影響MySQL的行為,使我們在輸入/匯入或更改資料時能使MySQL依我們希望的方式來處理資料.這個參數可在my.cnf或mysqld開機參數設定到整個資料庫,或在登入MySQL後以”set SQL_MODE =;”的方式臨時改變MySQL對當下的連線的行為模式.這些SQL_MODE中有指定個別特性的,也可組合性的以一個MODE代表好幾個特性的組合,同一個MySQL instance或連線可以有多個SQL_MODE組合,例如”set SQL_MODE=ANSI,NO_ENGINESUBSTITUTE,STRICT_TRANS_TABLES;”.這些MODE可以使資料操作(例如自外部系統匯入資料)更方便,相反的也可能造成使用者的混肴或對MySQL的誤解.主要的指定個別特性的SQL_MODE如下:
ALLOW_INVALID_DATES
使MySQL只會檢查月份是否在1到12之間,日期是否在1到31之間,而不會檢查整個日期的合理性,例如您想要存入前端使用者輸入的一模一樣的日期資料,而此時使用者輸入的日期是”2014-04-31”,如果沒將此SQL_MODE設起來,此值會轉成”0000-00-00”並傳出一個warning.
ANSI_QUOTES
能把“"”當成辨識字的引號就如同“`”一樣,在輸入的資料中有“字符時能使它順利輸入到MySQL.
ERROR_FOR_DIVISION_BY_ZERO
如果沒設此MODE以0當分母的算式會傳回NULL,也不會有warning.
HIGH_NOT_PRECEDENCE
運算式最前面的 “NOT”是否要優先處理,這和對舊版MySQL的向上相容有關,預設是NOT (boolean預算),若打開此MODE則NOT會加入boolean式運算的第一個運萛中
,以下例解釋:
#以下相當於NOT (1 BETWEEN -5 AND 5)
mysql> SET sql_mode = '';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 0
#以下相當於(NOT 1) BETWEEN -5 AND 5
mysql> SET sql_mode = 'HIGH_NOT_PRECEDENCE';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 1
IGNORE_SPACE
使funciton名和”(“間可否有空白,內建function名當成保留字,要以保留字當成辨識字必需在期前後加上引號,例如
mysql> CREATE TABLE count (i INT);
ERROR 1064 (42000): You have an error in your SQL syntax
#加上引號後:
mysql> CREATE TABLE `count` (i INT);
Query OK, 0 rows affected (0.00 sec)
NO_AUTO_CREATE_USER
下GRANT指令時如果指定的使用者不存在時預設會建一個新的使用者,以此mode將此功能關閉.
NO_AUTO_VALUE_ON_ZERO
在插入AUTO_INCREMENT欄位時的值為0或NULL值可產生自動跳號的值插入該欄位中,以此mode會使0值留下來而不會跳號,只有NULL值才會產生跳號值.
NO_BACKSLASH_ESCAPES
如果SQL指令中的值有'\'值會和MySQL的跳脫符號衝到,以此mode可使MySQL忽略跳脫符號,將'\'當成值插入欄位中.
NO_DIR_IN_CREATE
建表時忽略 INDEX DIRECTORY和DATA DIRECTORY, 當主從資料庫間的目錄位置不一樣時,在從服務器上有以此mode解決這個問題.
NO_ENGINE_SUBSTITUTION
如果沒設這個mode,建表時如果指定的storage engine不存在,會有warning,再以default storage engine來建這個表.
NO_FIELD_OPTIONS
下SHOW CREATE TABLE時不顯示MySQL特有的欄位選項,以使mysqldump產生的檔案較有可攜性.
NO_KEY_OPTIONS
下SHOW CREATE TABLE時不顯示MySQL特有的key選項,以使mysqldump產生的檔案較有可攜性.
NO_TABLE_OPTIONS
下SHOW CREATE TABLE指令時不顯示MySQL特有的table選項,以使mysqldump產生的檔案較有可攜性.
NO_UNSIGNED_SUBTRACTION
UNSIGNED整數相減預設產生不可以產生負值的結果,此mode可使結果為SIGNED(有負值).
NO_ZERO_DATE
決定日期欄是否可以為’0000-00-00’,5.6.17以後的版本此mode為deprecated.
NO_ZERO_IN_DATE
決定日期欄是否可有0(日或月).
ONLY_FULL_GROUP_BY
規定在SELECT命令中有GROUP BY子句時,SELECT的非總合(aggregate)欄位,HAVING清單中或ORDER BY子句中不可以有非GROUP BY子句沒有指定到的欄位.範仃如下:
mysql> SELECT name, address, MAX(age) FROM t GROUP BY name;
ERROR 1055 (42000): 't.address' isn't in GROUP BY
mysql> SELECT name, MAX(age) AS max_age FROM t GROUP BY name
-> HAVING max_age < 30;
Empty set (0.00 sec)
ERROR 1463 (42000): Non-grouping field 'max_age' is used in HAVING clause
第二個例子中改寫成HAVING MAX(age)就可執行因為該欄位在aggregate function.
PAD_CHAR_TO_FULL_LENGTH
CHAR欄位中的字串長度如果不到CHAR欄位定義的長度,設此MODE可將最後面補上空白字.例子如下:
mysql> CREATE TABLE t1 (c1 CHAR(10));
Query OK, 0 rows affected (0.37 sec)
mysql> INSERT INTO t1 (c1) VALUES('xy');
Query OK, 1 row affected (0.01 sec)
mysql> SET sql_mode = '';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT c1, CHAR_LENGTH(c1) FROM t1;
+------+-----------------+
| c1 | CHAR_LENGTH(c1) |
+------+-----------------+
| xy | 2 |
+------+-----------------+
1 row in set (0.00 sec)
mysql> SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT c1, CHAR_LENGTH(c1) FROM t1;
+------------+-----------------+
| c1 | CHAR_LENGTH(c1) |
+------------+-----------------+
| xy | 10 |
+------------+-----------------+
1 row in set (0.00 sec)
PIPES_AS_CONCAT
在後多資料庫認可以||代表字串連接,MySQL可以此Mode把||當成字串連接功能. ,而不是OR的同意字.
REAL_AS_FLOAT
把REAL當成FLOAT的同意字,沒有此設定,MySQL會將REAL當戶DOUBLE.
STRICT_ALL_TABLES
所有的storage engine,表都以strict mode處理.
STRICT_TRANS_TABLES
使交易型storage engine的表以strict mode處理.
STRICT_TRANS_TABLES
如果無法將值插入一個交易型的表,則放棄此指令.對非交易型的表,如果值出現在單一指令或在多行插入指令的第一個row則放棄此指令
TRADITIONAL
當有指令有錯誤資料時,如同典型資料庫一樣會有”error”而不時只有”warning.
組合的SQL Modes
以下組合幾個單項Mode成為一個SQL Mode,以方便使用,目的多為增加和某些第三方的資料庫的相容性:
ANSI
目當於一起使用REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE
DB2
目當於一起使用Equivalent to PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS.
MAXDB
目當於一起使用PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER.
MSSQL
目當於一起使用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.
ORACLE
目當於一起使用PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER.
POSTGRESQL
目當於一起使用_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS.
TRADITIONAL
目當於一起使用STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION.
沒有留言:
張貼留言