mysql的sql_mode 模式修改

1. sql_mode模式
mysql數據庫的中有一個環境變量sql_mode,定義了mysql應該支持的sql語法,數據校驗等!我們可以通過以下方式查看當前數據庫使用的sql_mode:
  1. mysql> select @@sql_mode;
  2. +----------------------------------------------------------------+
  3. | @@sql_mode |
  4. +----------------------------------------------------------------+
  5. | STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
  6. +----------------------------------------------------------------+
mysql> select @@sql_mode;
+----------------------------------------------------------------+
| @@sql_mode                                                     |
+----------------------------------------------------------------+
| STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+----------------------------------------------------------------+

或者通過查看系統變量方式:
  1. mysql> show variables like 'sql_mode%'\G;
  2. *************************** 1. row ***************************
  3. Variable_name: sql_mode
  4. Value: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
mysql> show variables like 'sql_mode%'\G;
*************************** 1. row ***************************
Variable_name: sql_mode
        Value: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

mysql5.0以上版本支持三種sql_mode模式:ANSI、TRADITIONAL和STRICT_TRANS_TABLES。
ANSI模式:寬鬆模式,對插入數據進行校驗,如果不符合定義類型或長度,對數據類型調整或截斷保存,報warning警告。
TRADITIONAL模式:嚴格模式,當向mysql數據庫插入數據時,進行數據的嚴格校驗,保證錯誤數據不能插入,報error錯誤。用於事物時,會進行事物的回滾。
STRICT_TRANS_TABLES模式:嚴格模式,進行數據的嚴格校驗,錯誤數據不能插入,報error錯誤。

1.2 ANSI模式
  1. mysql> set @@sql_mode=ANSI;
  2. Query OK, 0 rows affected (0.00 sec)
  3. mysql> create table test(name varchar(4), pass varchar(4));
  4. Query OK, 0 rows affected (0.03 sec)
  5. mysql> insert into test values('aaaaa','aaaaa'),('bbbb','bbbb');
  6. Query OK, 2 rows affected, 2 warnings (0.02 sec)
  7. Records: 2 Duplicates: 0 Warnings: 2
  8. mysql> show warnings;
  9. +---------+------+-------------------------------------------+
  10. | Level | Code | Message |
  11. +---------+------+-------------------------------------------+
  12. | Warning | 1265 | Data truncated for column 'name' at row 1 |
  13. | Warning | 1265 | Data truncated for column 'pass' at row 1 |
  14. +---------+------+-------------------------------------------+
  15. 2 rows in set (0.00 sec)
  16. mysql> select * from test;
  17. +------+------+
  18. | name | pass |
  19. +------+------+
  20. | aaaa | aaaa |
  21. | bbbb | bbbb |
  22. +------+------+
  23. 2 rows in set (0.00 sec)
mysql> set @@sql_mode=ANSI;
Query OK, 0 rows affected (0.00 sec)

mysql> create table test(name varchar(4), pass varchar(4));
Query OK, 0 rows affected (0.03 sec)

mysql> insert into test values('aaaaa','aaaaa'),('bbbb','bbbb');
Query OK, 2 rows affected, 2 warnings (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 2

mysql> show warnings;
+---------+------+-------------------------------------------+
| Level   | Code | Message                                   |
+---------+------+-------------------------------------------+
| Warning | 1265 | Data truncated for column 'name' at row 1 |
| Warning | 1265 | Data truncated for column 'pass' at row 1 |
+---------+------+-------------------------------------------+
2 rows in set (0.00 sec)

mysql> select * from test;
+------+------+
| name | pass |
+------+------+
| aaaa | aaaa |
| bbbb | bbbb |
+------+------+
2 rows in set (0.00 sec)

我們可以看到,在ANSI模式下,當我們插入數據時,未滿足列長度要求時,數據同樣會插入成功,但是對超出列長度的字段進行截斷,同時報告warning警告。

1.3 STRICT_TRANS_TABLES模式
  1. mysql> set @@sql_mode=STRICT_TRANS_TABLES;
  2. Query OK, 0 rows affected (0.00 sec)
  3. mysql> create table test(name varchar(4), pass varchar(4));
  4. Query OK, 0 rows affected (0.02 sec)
  5. mysql> insert into test values('aaaaa','aaaaa'),('bbbb','bbbb');
  6. ERROR 1406 (22001): Data too long for column 'name' at row 1
  7. mysql> show errors;
  8. +-------+------+------------------------------------------+
  9. | Level | Code | Message |
  10. +-------+------+------------------------------------------+
  11. | Error | 1406 | Data too long for column 'name' at row 1 |
  12. +-------+------+------------------------------------------+
  13. 1 row in set (0.00 sec)
  14. mysql> select * from test;
  15. Empty set (0.00 sec)
mysql> set @@sql_mode=STRICT_TRANS_TABLES;
Query OK, 0 rows affected (0.00 sec)

mysql> create table test(name varchar(4), pass varchar(4));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into test values('aaaaa','aaaaa'),('bbbb','bbbb');
ERROR 1406 (22001): Data too long for column 'name' at row 1

mysql> show errors;
+-------+------+------------------------------------------+
| Level | Code | Message                                  |
+-------+------+------------------------------------------+
| Error | 1406 | Data too long for column 'name' at row 1 |
+-------+------+------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from test;
Empty set (0.00 sec)

我們可以看到,在STRICT_TRANS_TABLES模式下,當我們插入數據時,mysql會嚴格的進行數據的校驗,當發現插入列值未滿足要求,直接報告error錯誤,保證了錯誤數據無法插入到數據庫中。

1.3 TRADITIONAL模式
  1. mysql> set @@sql_mode=TRADITIONAL;
  2. Query OK, 0 rows affected (0.00 sec)
  3. mysql> create table test(name varchar(4), pass varchar(4));
  4. Query OK, 0 rows affected (0.02 sec)
  5. mysql> insert into test values('aaaaa','aaaaa'),('bbbb','bbbb');
  6. ERROR 1406 (22001): Data too long for column 'name' at row 1
  7. mysql> show errors;
  8. +-------+------+------------------------------------------+
  9. | Level | Code | Message |
  10. +-------+------+------------------------------------------+
  11. | Error | 1406 | Data too long for column 'name' at row 1 |
  12. +-------+------+------------------------------------------+
  13. 1 row in set (0.00 sec)
  14. mysql> select * from test;
  15. Empty set (0.00 sec)
mysql> set @@sql_mode=TRADITIONAL;
Query OK, 0 rows affected (0.00 sec)

mysql> create table test(name varchar(4), pass varchar(4));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into test values('aaaaa','aaaaa'),('bbbb','bbbb');
ERROR 1406 (22001): Data too long for column 'name' at row 1

mysql> show errors;
+-------+------+------------------------------------------+
| Level | Code | Message                                  |
+-------+------+------------------------------------------+
| Error | 1406 | Data too long for column 'name' at row 1 |
+-------+------+------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from test;
Empty set (0.00 sec)

TRADITIONAL模式與STRICT_TRANS_TABLES模式執行的結果,在這種情況下一致。
  1. mysql> select @@sql_mode\G;
  2. *************************** 1. row ***************************
  3. @@sql_mode: STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,E
  4. RROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
  5. 1 row in set (0.00 sec)
mysql> select @@sql_mode\G;
*************************** 1. row ***************************
@@sql_mode: STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,E
RROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
1 row in set (0.00 sec)

看一下TRADITIONAL模式,我們發現在TRADITIONAL模式下,對所有的事務存儲引擎,非事務存儲引擎檢查,日期類型中的月和日部分不能包含0,不能有0這樣的日期(0000-00-00),數據不能除0,禁止grant自動創建新用戶等一些校驗。

注意:我們這裏設置的sql_mode都是session級別的。另外,可以直接修改my.ini文件,找到sql_mode,然後設置新的模式即可!

例如:

vi /etc/my.cnf

在[mysqld]下面添加如下列:

sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

發佈了56 篇原創文章 · 獲贊 5 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章