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严格模式,实现了数据的严格校验,对不符合数据类型的错误数据不能插入表中,保证了数据的准确性。

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

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

  1. mysql> set session sql_mode="ANSI"; #ANSI模式
  2. Query OK, 0 rows affected (0.00 sec)
  3. mysql> select @@sql_mode;
  4. +--------------------------------------------------------------------------------+
  5. | @@sql_mode |
  6. +--------------------------------------------------------------------------------+
  7. | REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI |
  8. +--------------------------------------------------------------------------------+
  9. 1 row in set (0.00 sec)
  10. mysql> insert into transaction values(null,'1111111111111111222222222222223333333333333',2000);
  11. Query OK, 1 row affected, 1 warning (0.10 sec)
  12. mysql> select name from transaction where id=27; # 允许数据插入但多余长度被截断
  13. +----------------------+
  14. | name |
  15. +----------------------+
  16. | 11111111111111112222 |
  17. +----------------------+
  18. 1 row in set (0.00 sec)

SQL Mode的常见功能

1 校验日期格式的合法性

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

  1. mysql> select @@sql_mode; # ANSI模式
  2. +--------------------------------------------------------------------------------+
  3. | @@sql_mode |
  4. +--------------------------------------------------------------------------------+
  5. | REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI |
  6. +--------------------------------------------------------------------------------+
  7. 1 row in set (0.00 sec)
  8. mysql> create table t1(d date);
  9. Query OK, 0 rows affected (0.29 sec)
  10. mysql> SET @invalidData='2017-2-31';
  11. Query OK, 0 rows affected (0.00 sec)
  12. mysql> insert into t1 values(@invalidData);
  13. Query OK, 1 row affected, 1 warning (0.07 sec)
  14. mysql> select * from t1; # ANSI模式支持非法数据插入,插入值为“0000-00-00"
  15. +------------+
  16. | d |
  17. +------------+
  18. | 0000-00-00 |
  19. +------------+
  20. 1 row in set (0.00 sec)
  21. mysql> set session sql_mode="TRADITIONAL"; # 严格模式下报错
  22. Query OK, 0 rows affected, 1 warning (0.00 sec)
  23. mysql> insert into t1 values(@invalidData);
  24. ERROR 1292 (22007): Incorrect date value: '2017-2-31' for column 'd' at row 1
  25. mysql>

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

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

  1. mysql> select @@sql_mode; #ANSI模式下,没有启用NO_BACKSLASH_ESCAPES
  2. +--------------------------------------------------------------------------------+
  3. | @@sql_mode |
  4. +--------------------------------------------------------------------------------+
  5. | REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI |
  6. +--------------------------------------------------------------------------------+
  7. 1 row in set (0.00 sec)
  8. mysql> set @escapeStr = '\\a\s\t\n123';
  9. Query OK, 0 rows affected (0.00 sec)
  10. mysql> insert into t2 values(@escapeStr);
  11. Query OK, 1 row affected (0.06 sec)
  12. mysql> select * from t2; # 出现转义字符被执行
  13. +----------+
  14. | url |
  15. +----------+
  16. | \as
  17. 123 |
  18. +----------+
  19. 1 row in set (0.00 sec)
  20. mysql> set session sql_mode='ANSI,NO_BACKSLASH_ESCAPES';
  21. Query OK, 0 rows affected (0.00 sec)
  22. mysql> set @escapeStr = '\\begin';
  23. Query OK, 0 rows affected (0.00 sec)
  24. mysql> truncate table t2;
  25. Query OK, 0 rows affected (0.20 sec)
  26. mysql> insert into t2 values(@escapeStr);
  27. Query OK, 1 row affected (0.04 sec)
  28. mysql> select * from t2;
  29. +---------+
  30. | url |
  31. +---------+
  32. | \\begin |
  33. +---------+
  34. 1 row in set (0.00 sec)
  35. mysql>

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

  1. mysql> select '1'||'2' as A, concat('3', '4') as B;
  2. +----+----+
  3. | A | B |
  4. +----+----+
  5. | 12 | 34 |
  6. +----+----+
  7. 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。

SQL Mode的更多相关文章

  1. 最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目

    最近帮客户实施的基于SQL Server AlwaysOn跨机房切换项目 最近一个来自重庆的客户找到走起君,客户的业务是做移动互联网支付,是微信支付收单渠道合作伙伴,数据库里存储的是支付流水和交易流水 ...

  2. SQL Server 大数据搬迁之文件组备份还原实战

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 解决方案(Solution) 搬迁步骤(Procedure) 搬迁脚本(SQL Codes) ...

  3. Sql Server系列:分区表操作

    1. 分区表简介 分区表在逻辑上是一个表,而物理上是多个表.从用户角度来看,分区表和普通表是一样的.使用分区表的主要目的是为改善大型表以及具有多个访问模式的表的可伸缩性和可管理性. 分区表是把数据按设 ...

  4. SQL Server中的高可用性(2)----文件与文件组

        在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性.在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性.SQL Server允许在某些文件损坏或离线的情况下,允 ...

  5. EntityFramework Core Raw SQL

    前言 本节我们来讲讲EF Core中的原始查询,目前在项目中对于简单的查询直接通过EF就可以解决,但是涉及到多表查询时为了一步到位就采用了原始查询的方式进行.下面我们一起来看看. EntityFram ...

  6. 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)

    从0开始搭建SQL Server AlwaysOn 第一篇(配置域控) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnb ...

  7. 从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群)

    从0开始搭建SQL Server AlwaysOn 第二篇(配置故障转移集群) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...

  8. 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)

    从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://w ...

  9. 从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点)

    从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...

  10. SQL Server on Linux 理由浅析

    SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...

随机推荐

  1. 指针总结指向const的指针、const指针、指向const指针的const指针

    指针的一些总结   const与指针 指向const的指针指的是指针指向的数据是常量,不可以被修改,但指针变量本身可以被修改,如const int *p:严格说不能用指针间接修改指向的数据,但该变量可 ...

  2. Django---Django的中间件

    Django---Django的中间件 一丶中间件介绍 什么是中间件 官方的说法:中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Dj ...

  3. 【转载】C#的DataTable使用NewRow方法创建新表格行

    在C#的DataTable数据表格操作过程中,DataRow类表示DataTable中的数据行信息,但DataRow没有可以直接实例化的构造方法,在创建DataTable的新行的时候,不可直接使用Da ...

  4. 在windows 10 64位系统下安装TensorFlow

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/mao_hui_fei/article/de ...

  5. 3.kettle-定时执行任务

    kettle定时任务可以 用两种方法. 第一种如下,但这种缺点也很明显,就是该job窗口不能关闭.(重复时间含义问题截图来自https://www.cnblogs.com/biehongli/p/10 ...

  6. Linux开发环境配置大全

    Linux开发环境配置 零章:通过xshell在linux上安装JDK8 壹章:通过xshell在linux上安装tomcat8 贰章:通过xshell在linux上安装mysql5.7(终极版) 叁 ...

  7. PS用户配置服务连接出错

    PS用户配置服务连接出错 [2019-07-30 14:58:25.475]-[INFO ]-[xxxx.profileserver.service.ProfileServerImpl:1430][1 ...

  8. java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购

    此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...

  9. Centos系统的升级

    文章来源:https://blog.csdn.net/kikajack/article/details/79396793 系统及内核版本: [root@node5 ~]# cat /etc/redha ...

  10. 浅谈Flask 中的 线程局部变量 request 原理

    2017-11-27 17:25:11 晚橙 阅读数 600更多 分类专栏: Flask python 多线程   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出 ...