SQL Mode简介

在MySQL中,SQL Mode常常用来解决以下问题:

1.通过设置SQL Mode,可以完成不同严格程度的数据校验,有效保证数据准确性。

2.通过设置SQL Mode为ANSI模式,来保证大多数SQL是符合标准的SQL语法,这样应用在不同数据库之间迁移时,则不需要对业务SQL进行较大修改。

3.在不同数据库进行数据迁移时,通过设置SQL Mode可以使得MySQL上的数据更方便迁移到目标数据库

在MySQL5.7.18上,查询默认的SQL Mode(@@sql_mode)为STRICT_TRANS_TABLES, NO_ENGINE_SUBSTITUTION

STRICT_TRANS_TABLES严格模式,实现了数据的严格校验,对不符合数据类型的错误数据不能插入表中,保证了数据的准确性。

mysql> select @@sql_mode;  # 严格模式
+--------------------------------------------+
| @@sql_mode |
+--------------------------------------------+
| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+--------------------------------------------+
1 row in set (0.00 sec) mysql> desc transaction;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | UNI | NULL | |
| account | double | YES | | NULL | |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec) mysql>insert into transaction values(null, "123456789abcdefghijkkkkkkkkkkkkkkk", 2000);
ERROR 1406 (22001): Data too long for column 'name' at row 1

如果更改SQL Mode为ANSI模式,错误数据也会被插入表中, 对于超过长度的值,会进行截取

mysql> set session sql_mode="ANSI";  #ANSI模式
Query OK, 0 rows affected (0.00 sec) mysql> select @@sql_mode;
+--------------------------------------------------------------------------------+
| @@sql_mode |
+--------------------------------------------------------------------------------+
| REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI |
+--------------------------------------------------------------------------------+
1 row in set (0.00 sec) mysql> insert into transaction values(null,'1111111111111111222222222222223333333333333',2000);
Query OK, 1 row affected, 1 warning (0.10 sec) mysql> select name from transaction where id=27; # 允许数据插入但多余长度被截断
+----------------------+
| name |
+----------------------+
| 11111111111111112222 |
+----------------------+
1 row in set (0.00 sec)

SQL Mode的常见功能

1 校验日期格式的合法性

例如:给定一个非法日期如“2019-2-31”进行插入操作

mysql> select @@sql_mode;  # ANSI模式
+--------------------------------------------------------------------------------+
| @@sql_mode |
+--------------------------------------------------------------------------------+
| REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI |
+--------------------------------------------------------------------------------+
1 row in set (0.00 sec) mysql> create table t1(d date);
Query OK, 0 rows affected (0.29 sec) mysql> SET @invalidData='2017-2-31';
Query OK, 0 rows affected (0.00 sec) mysql> insert into t1 values(@invalidData);
Query OK, 1 row affected, 1 warning (0.07 sec) mysql> select * from t1; # ANSI模式支持非法数据插入,插入值为“0000-00-00"
+------------+
| d |
+------------+
| 0000-00-00 |
+------------+
1 row in set (0.00 sec) mysql> set session sql_mode="TRADITIONAL"; # 严格模式下报错
Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> insert into t1 values(@invalidData);
ERROR 1292 (22007): Incorrect date value: '2017-2-31' for column 'd' at row 1
mysql>

2 在ANSI模式下执行MOD(x, 0)不会出错,插入时数值变为NULL

3 启用NO_BACKSLASH_ESCAPES使得反斜杠成普通字符。

mysql> select @@sql_mode;  #ANSI模式下,没有启用NO_BACKSLASH_ESCAPES
+--------------------------------------------------------------------------------+
| @@sql_mode |
+--------------------------------------------------------------------------------+
| REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI |
+--------------------------------------------------------------------------------+
1 row in set (0.00 sec) mysql> set @escapeStr = '\\a\s\t\n123';
Query OK, 0 rows affected (0.00 sec) mysql> insert into t2 values(@escapeStr);
Query OK, 1 row affected (0.06 sec) mysql> select * from t2; # 出现转义字符被执行
+----------+
| url |
+----------+
| \as
123 |
+----------+
1 row in set (0.00 sec) mysql> set session sql_mode='ANSI,NO_BACKSLASH_ESCAPES';
Query OK, 0 rows affected (0.00 sec) mysql> set @escapeStr = '\\begin';
Query OK, 0 rows affected (0.00 sec) mysql> truncate table t2;
Query OK, 0 rows affected (0.20 sec) mysql> insert into t2 values(@escapeStr);
Query OK, 1 row affected (0.04 sec) mysql> select * from t2;
+---------+
| url |
+---------+
| \\begin |
+---------+
1 row in set (0.00 sec) mysql>

4 启用PIPES_AS_CONTACT模式。将“||”视为字符串连接符号(同CONCAT)

mysql> select '1'||'2' as A, concat('3', '4') as B;
+----+----+
| A | B |
+----+----+
| 12 | 34 |
+----+----+
1 row in set (0.00 sec)

常见的SQL Mode

sql_mode值 描述
ANSI 等同于REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI
STRICT_TRANS_TABLES 适用于事务处理,对于非法数据直接抛出错误,而非warning
TRADITIONAL 等同于STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION, 属于严格模式,对于非法数据直接抛出错误,可用在事务表中,出现错误立即回滚

SQL Mode在数据迁移中如何使用

MySQL提供了很多数据库的组合模式,例如“ORACLE、POSTGRESQL”等

其组合形式可参考https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html[https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html]: https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html。

最新文章

  1. UITableView在设置contentOffset的同时也reload,造成tableView的contentOffset偏差
  2. 来自平时工作中的javascript知识的积累---持续补充中
  3. HTML5 Cheat sheet PNG帮助手册(标签、事件、兼容)
  4. UNIX相关知识
  5. Unity 读取、写入自定义路径文件,调用System.Windows.Forms
  6. 字符串格式化 String.format() 案例
  7. 【最大流】【HDU3338】【Kakuro Extension】
  8. ActivityManager
  9. asp.net 在新的页面打开的问题。
  10. 用Vim 加密文本
  11. Java 生产者消费者模式详细分析
  12. 重构:以Java POI 导出EXCEL为例
  13. hibernate之HQL,Criteria与SQL
  14. python3 函数注意要点
  15. Xvector in Kaldi nnet3
  16. increase the minSdkVersion to 26
  17. SpringBatch Sample (二)(CSV文件操作)
  18. SAP自开发程序
  19. Carbon document
  20. Download SQL Server Management Studio (SSMS)下载地址

热门文章

  1. MySQL之SQL演练(四)
  2. Throwable中几个常见方法。
  3. 电脑远程连接windows阿里云服务器解决卡顿【小白教程】
  4. France Alternative forms Fraunce
  5. 汽车行业MES系统在产品追溯方面的应用分析
  6. android中fragment卡顿的原因
  7. Maven国内源设置 - OSChina国内源失效了,别更新了
  8. js修改页面标题 title
  9. Xshell 配置密钥
  10. Linux不管上一条命令成功还是失败都执行下一个命令的方法