一 声明

标红部分为重点了解

原文:https://segmentfault.com/a/1190000005936172

二 SQL_MODE参数值

官方手册专门有一节介绍 https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html 。 SQL Mode 定义了两个方面:MySQL应支持的SQL语法,以及应该在数据上执行何种确认检查。

1. SQL语法支持类

    • ONLY_FULL_GROUP_BY 对于GROUP BY聚合操作,如果在SELECT中的列、HAVING或者ORDER BY子句的列,没有在GROUP BY中出现,那么这个SQL是不合法的。是可以理解的,因为不在 group by 的列查出来展示会有矛盾。
      在5.7中默认启用,所以在实施5.6升级到5.7的过程需要注意:

 Expression #1 of SELECT list is not in GROUP BY
clause and contains nonaggregated column
'1066export.ebay_order_items.TransactionID' which
is not functionally dependent on columns in GROUP BY
clause; this is incompatible with sql_mode=only_full_group_by
  • ANSI_QUOTES 启用 ANSI_QUOTES 后,不能用双引号来引用字符串,因为它被解释为识别符,作用与 ` 一样。设置它以后,update t set f1="" ...,会报 Unknown column '' in 'field list 这样的语法错误。

  • PIPES_AS_CONCAT 将 || 视为字符串的连接操作符而非 或 运算符,这和Oracle数据库是一样的,也和字符串的拼接函数 CONCAT() 相类似。

  • NO_TABLE_OPTIONS 使用 SHOW CREATE TABLE 时不会输出MySQL特有的语法部分,如 ENGINE ,这个在使用 mysqldump 跨DB种类迁移的时候需要考虑。

  • NO_AUTO_CREATE_USER 字面意思不自动创建用户。在给MySQL用户授权时,我们习惯使用 GRANT ... ON ... TO dbuser 顺道一起创建用户。设置该选项后就与oracle操作类似,授权之前必须先建立用户。5.7.7开始也默认了。

2. 数据检查类

  • NO_ZERO_DATE 认为日期 '0000-00-00' 非法,与是否设置后面的严格模式有关。

    1. 如果设置了严格模式,则 NO_ZERO_DATE 自然满足。但如果是 INSERT IGNORE 或 UPDATE IGNORE,'0000-00-00'依然允许且只显示warning

    2. 如果在非严格模式下,设置了NO_ZERO_DATE,效果与上面一样,'0000-00-00'允许但显示warning;如果没有设置NO_ZERO_DATE,no warning,当做完全合法的值。

    3. NO_ZERO_IN_DATE情况与上面类似,不同的是控制日期和天,是否可为 0 ,即 2010-01-00 是否合法。

  • NO_ENGINE_SUBSTITUTION 使用 ALTER TABLECREATE TABLE 指定 ENGINE 时, 需要的存储引擎被禁用或未编译,该如何处理。启用NO_ENGINE_SUBSTITUTION时,那么直接抛出错误;不设置此值时,CREATE用默认的存储引擎替代,ATLER不进行更改,并抛出一个 warning .

  • STRICT_TRANS_TABLES 设置它,表示启用严格模式。

很多集成环境自带的MySQL貌似都没有开启MySQL的严格模式,何为MySQL的严格模式,简单来说就是MySQL自身对数据进行严格的校验(格式、长度、类型等),比如一个整型字段我们写入一个字符串类型的数据,在非严格模式下MySQL不会报错,同样如果定义了char或varchar类型的字段,当写入或更新的数据超过了定义的长度也不会报错。

我认为这个对于编程来说没有任何好处,虽然我们尽量在代码中做数据校验。MySQL开启了严格模式从一定程序上来讲是对我们代码的一种测试,如果我们的开发环境没有开启严格模式在开发过程中也没有遇到错误,那么在上线或代码移植的时候将有可能出现不兼容的情况,因此在开发过程做最好开启MySQL的严格模式。

注意 STRICT_TRANS_TABLES 不是几种策略的组合,单独指 INSERTUPDATE出现少值或无效值该如何处理:

    1. 如果把 '' 传给int,严格模式下非法,若启用非严格模式则变成0,产生一个warning

    2. Out Of Range,变成插入最大边界值

    3. A value is missing when a new row to be inserted does not contain a value for a non-NULL column that has no explicit DEFAULT clause in its definition

上面并没有囊括所有的 SQL Mode,选了几个代表性的,详细还是 看手册

sql_mode一般来说很少去关注它,没有遇到实际问题之前不会去启停上面的条目。我们常设置的 sql_mode 是 ANSISTRICT_TRANS_TABLESTRADITIONAL,ansi和traditional是上面的几种组合。

  • ANSI:更改语法和行为,使其更符合标准SQL
    相当于REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE

  • TRADITIONAL:更像传统SQL数据库系统,该模式的简单描述是当在列中插入不正确的值时“给出错误而不是警告”。
    相当于 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

  • ORACLE:相当于 PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER

无论何种mode,产生error之后就意味着单条sql执行失败,对于支持事务的表,则导致当前事务回滚;但如果没有放在事务中执行,或者不支持事务的存储引擎表,则可能导致数据不一致。MySQL认为,相比直接报错终止,数据不一致问题更严重。于是 STRICT_TRANS_TABLES 对非事务表依然尽可能的让写入继续,比如给个"最合理"的默认值或截断。而对于 STRICT_ALL_TABLES,如果是单条更新,则不影响,但如果更新的是多条,第一条成功,后面失败则会出现部分更新。

5.6.6 以后版本默认就是NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,5.5默认为 '' 。

三 设置 sql_mode

查看

#1、查看当前连接会话的sql模式:
mysql> select @@session.sql_mode;
或者从环境变量里取
mysql> show variables like "sql_mode"; #2、查看全局sql_mode设置:
mysql> select @@global.sql_mode;
只设置global,需要重新连接进来才会生效

设置

#形式如
mysql> set sql_mode='';
mysql> set global sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES'; #如果是自定义的模式组合,可以像下面这样
Adding only one mode to sql_mode without removing existing ones:
mysql> SET sql_mode=(SELECT CONCAT(@@sql_mode,',<mode_to_add>')); Removing only a specific mode from sql_mode without removing others:
mysql> SET sql_mode=(SELECT REPLACE(@@sql_mode,'<mode_to_remove>','')); #配置文件里面设置 sql-mode=""

SQL_MODE的更多相关文章

  1. Mysql中sql_mode详解

    阅读目录 简介 sql_mode常用值 session与global 简介 MySQL服务器能够工作在不同的SQL模式下,并能针对不同的客户端以不同的方式应用这些模式.这样,应用程序就能对服务器操作进 ...

  2. uct框架数据库sql文件导入错误之 sql_mode

    uct框架在导入sql文件时可能会出现一种错误 ERROR 1101 (42000): BLOB/TEXT column 'brief' can't have a default value 这是由于 ...

  3. mysql的sql_mode模式

    在oracle或sqlserver中,如果某个表的字段设置成not null,insert或update时不给这个字段赋值,比如下面这样: 表t_test(id,name)中id,name都不允许为空 ...

  4. MYSQL5.7版本sql_mode=only_full_group_by问题

    具体出错提示: [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggr ...

  5. MySQL 5.7版本sql_mode=only_full_group_by问题

    用到GROUP BY 语句查询时com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #2 of SELECT l ...

  6. mysql的sql_mode合理设置

    mysql的sql_mode合理设置 sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入.在生产环境必须将这个值设置为严格模式,所以 ...

  7. MySQL 5.7.9版本sql_mode=only_full_group_by问题

    用到GROUP BY 语句查询时com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #2 of SELECT l ...

  8. mysql的sql_mode 模式修改 my.cnf

    1. sql_mode模式 mysql数据库的中有一个环境变量sql_mode,定义了mysql应该支持的sql语法,数据校验等!我们可以通过以下方式查看当前数据库使用的sql_mode: mysql ...

  9. mysql SQL_MODE设置

    1.1.   SQL_MODE设置 在生产环境中强烈建议将这个值设置为严格模式,这样有些问题可以在数据库的设计和开发阶段就能实现,而如果在生产环境下运行数据库后发现这类问题,那么修改的代价将变得十分巨 ...

  10. 十二、mysql sql_mode 简学

    .一般默认情况下sql_mode默认为空,也就是不严格的sql检查 .如果sql_mode为空的情况下,测试: )); //定义一个name字段长度为定长2的tt3表 insert into tt3 ...

随机推荐

  1. 怎样下载JDBC驱动

    MySQL官网: https://www.mysql.com/ 请注意: 需要把mysql-connector-java-5.1.45-bin.jar放到C:\JMeter\apache-jmeter ...

  2. Java 递归 反射 正则表达式

    一 递归 1. 就是函数自身调用自身 (就是在栈内存中不断的加载同一个函数) 2. 什么时候用递归呢? 当一个功能被重复使用 而每一次使用该功能时的参数不确定 都由上次的功能元素结果来确定 简单说: ...

  3. lesson 18 Electric currents in modern art

    lesson18 Electric currents in modern art electricity n. 电力:电流; electric adj. 电的:电动的; electronic adj. ...

  4. javaee开发工具及环境配置过程

    在配置javaee开发环境的过程中遇到过很多问题,在此系统的整理一下我之前的配置过程 注:配置过程学习自<JSP&Servlet学习笔记(第二版)>详细过程可以阅读此书.在文章的最 ...

  5. CsvHelper文档-2读

    CsvHelper文档-2读 这个库默认不需要做任何设置就可以很容易的使用它.如果你的类属性名称直接匹配csv的标题名称,那么可以按照下面的实例来用: (以下所有的代码都需要引用using csvhe ...

  6. 【转】jQuery最佳实践

    上周,我整理了<jQuery设计思想>. 那篇文章是一篇入门教程,从设计思想的角度,讲解"怎么使用jQuery".今天的文章则是更进一步,讲解"如何用好jQu ...

  7. v-if或者v-repeat等不起作用

    v-if或者v-for等不起作用 在项目中,有时遇到了v-if或v-for等形式时,页面没起作用.以下可能是出现这些问题的原因: 1.绑定值是接口返回的某个属性值,而这个属性值不存在data()中,这 ...

  8. Phpcms V9导航循环下拉菜单的调用技巧

    这个方法基于PC V9官方模版中的调用方法,然后利用后台的“Phpcms V9菜单是否显示设置”控制菜单是否显示出来. 先看看最后的效果: 调用方法: <div id="navbar& ...

  9. Java中抽象类也能实例化

    在Java中抽象类真的不能实例化么? 在学习的过程中,发现了一个问题,抽象类在没有实现所有的抽象方法前是不可以通过new来构建该对象的,但是抽象方法却是可以有自己的构造方法的.这样就把我搞糊涂了,既然 ...

  10. TCP系列16—重传—6、基础快速重传(Fast Retransmit)

    一.快速重传介绍 按照TCP协议,RTO超时重传是一个非常重要的事件,当RTO超时的时候,TCP会同时通过两种方式非常谨慎的降低发送数据包的速率,一种是基于拥塞控制削减发送窗口的大小,另外一个是通过指 ...