1、sql_mode=only_full_group_by 导致的语法错误问题 MySQLSyntaxErrorException

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'db.table.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

该问题是因为MySQL Server 默认开启了 sql_mode=only_full_group_by 模式,此模式要求 group by 字段必须出现在查询项中(select),否则就会报出该错误。解决的方式也很简单见(5),借着这个异常问题,借机在本文就来学习一下,MySQL 5.7 中的 sql_mode。

2、简介

MySQL服务器可以在不同的SQL模式下运行,并且可以针对不同的客户端以不同的方式应用这些模式,具体取决于sql_mode系统变量的值。可以设置全局SQL模式以匹配站点服务器的操作要求,每个应用程序也可以设置会话级别的SQL模式来满足自己的需求。

sql_mode 模式会影响MYSQL语法及执行数据的验证检查。这使得在不同环境中使用MySQL以及将MySQL与其他数据库服务器一起使用变得更加容易。

3、MySQL 5.7 和 MySQL 5.8 中默认的sql_mode

3.1、查询sql_mode的方式

查询全局sql_mode
SELECT @@GLOBAL.sql_mode;
查询当前会话sql_mode
SELECT @@SESSION.sql_mode;

3.2、MySQL 5.7中的默认SQL模式:

ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_ENGINE_SUBSTITUTION

MySQL 5.7.5 中默认SQL模式添加了 ONLY_FULL_GROUP_BY和STRICT_TRANS_TABLES

MySQL 5.7.7 中默认SQL模式添加了 NO_AUTO_CREATE_USER

MySQL 5.7.8 中默认SQL模式添加了 ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE 和 NO_ZERO_IN_DATE

3.3、MySQL 5.8中的默认SQL模式(去掉了 NO_AUTO_CREATE_USER):

ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_ENGINE_SUBSTITUTION.

4、MySQL 5.7 中 sql_mode 的变化

1、在MySQL 5.7.22中,这些SQL模式已被弃用,将在未来版本的MySQL中删除:

DB2,MAXDB,MSSQL,MYSQL323,MYSQL40,ORACLE,POSTGRESQL,NO_FIELD_OPTIONS,NO_KEY_OPTIONS,NO_TABLE_OPTIONS。

2、在MySQL 5.7中,默认情况下启用了 ONLY_FULL_GROUP_BY SQL 模式,因为GROUP BY处理变得更加复杂,包括检测功能依赖性。

3、但是你会发现启用 ONLY_FULL_GROUP_BY 会导致现有应用程序的查询被拒绝,解决办法如下:

- GROUP BY列包含在select 查询项中,或者使用ANY_VALUE()引用非聚合列

- 如果无法修改有问题的查询(例如,如果它是由第三方应用程序生成),请在服务器启动时将sql_mode系统变量设置为不启用 ONLY_FULL_GROUP_BY。

4、在MySQL 5.7中,不推荐使用ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE和NO_ZERO_IN_DATE SQL模式。长期计划是将三种模式包含在严格的SQL模式中,并在未来的MySQL版本中将它们作为显式模式删除。为了使MySQL 5.7与MySQL 5.6严格模式(strict mode)兼容并为受影响的应用程序提供额外的修改时间,以下情况适用:

- ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE和NO_ZERO_IN_DATE不是严格SQL模式的一部分,但它们与严格模式一起使用。提醒一下,如果启用它们而不启用严格模式,则会发出警告,反之亦然。

- 默认情况下启用ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_DATE和NO_ZERO_IN_DATE。

通过以上方式的更改,默认情况下仍会启用更严格的数据检查,但可以在当前需要或必须执行此操作的环境中禁用各个模式。

5、设置 sql_mode

sql_mode 的设置有三种方式,分别是启动命令行设置、配置文件设置、运行时设置,多个模式之间使用逗号隔开

5.1、启动命令行设置

服务启动时,在命令行使用 --sql-mode =“modes” (设置sql_mode) 或 --sql-mode =“” (清空sql_mode)

5.2、配置文件设置

在Unix操作系统下配置文件 my.cnf 设置 sql-mode =“modes” (设置sql_mode) 或 sql-mode =“”(清空sql_mode)

在Windows系统下配置文件 my.ini 中设置 sql-mode =“modes” 或 sql-mode =“”(清空sql_mode)

5.3、运行时设置

要在运行时更改SQL模式,使用SET语句设置全局或会话sql_mode系统变量:

SET GLOBAL sql_mode = 'modes';
SET SESSION sql_mode = 'modes';

设置GLOBAL变量需要SUPER权限,作用于修改后新连接的所有客户端的操作。 设置SESSION变量仅影响当前客户端。 每个客户端都可以随时更改其会话sql_mode值。

SQL模式和用户定义的分区【重点】

在创建数据并将数据插入分区表后更改服务器SQL模式可能会导致此类表的行为发生重大更改,并可能导致数据丢失或损坏。强烈建议您在使用用户定义的分区创建表后永远不要更改SQL模式。复制分区表时,主服务器和从服务器上的不同SQL模式也会导致问题。 为获得最佳结果,应始终在主服务器和从服务器上使用相同的服务器SQL模式。

6、sql_mode 常用值

此处只列出部分值,并非全部

ONLY_FULL_GROUP_BY

    对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中。

NO_AUTO_VALUE_ON_ZERO

    该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户希望插入的值为0,该列又是自增长的,那么这个选项就有用了。

STRICT_TRANS_TABLES

    在该模式下,如果一个值不能插入到一个事物表中,则中断当前的操作,对非事物表不做限制

NO_ZERO_IN_DATE

    在严格模式下,不允许日期和月份为零

NO_ZERO_DATE

    设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告。

ERROR_FOR_DIVISION_BY_ZERO

    在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如 果未给出该模式,那么数据被零除时MySQL返回NULL

NO_AUTO_CREATE_USER

    禁止GRANT创建密码为空的用户

NO_ENGINE_SUBSTITUTION

    如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常

PIPES_AS_CONCAT

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

ANSI_QUOTES

    启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符

HIGH_NOT_PRECEDENCE

    NOT运算符的优先级使得诸如 NOT a BETWEEN b AND c 之类的表达式被解析为NOT(a BETWEEN b AND c)

    mysql> SET sql_mode = '';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 0
mysql> SET sql_mode = 'HIGH_NOT_PRECEDENCE';
mysql> SELECT NOT 1 BETWEEN -5 AND 5;
-> 1 IGNORE_SPACE
允许函数名和括号【(】之间的空格。这会导致内置函数名被视为保留字。
IGNORE_SPACE SQL模式适用于内置函数,而不适用于用户定义的函数或存储函数。 无论是否启用IGNORE_SPACE,始终允许在UDF或存储的函数名后面包含空格。 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)

参考资料:https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html

MySQL 5.7:聊聊sql_mode的更多相关文章

  1. Mysql only_full_group_by以及其他关于sql_mode原因报错详细解决方案

    Mysql only_full_group_by以及其他关于sql_mode原因报错详细解决方案 网上太多相关资料,但是抄袭严重,有的讲的也是之言片语的,根本不连贯(可能知道的人确实不想多说) 我总共 ...

  2. MySQL 5.7版本sql_mode=only_full_group_by问题

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

  3. mysql 5.7~默认sql_mode解读

    当5.6升级到5.7时,首先要注意的就是sql_mode对业务的影响 大概可以分为几类1 共同支持,如果你的5.6和5.7sql_mode配置支持的交集一样,那么不用考虑2 5.7细说  1 ONLY ...

  4. MySQL 5.7版本 sql_mode=only_full_group_by 问题

    具体错误: SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in ...

  5. MySQL 5.7 模式(SQL_MODE)详细说明 转

    5.7 默认模式: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION ...

  6. mysql sql_mode 之 NO_ENGINE_SUBSTITUTION

    知识储备: 1.mysql 有众多的存储引擎,然而只有一个默认的存储引擎,通常来说它是innodb 2.mysql 可以通过sql_mode 来控制mysql 数据库的行为,今天我们要讲的就是no_e ...

  7. 为什么在有的服务器上禅道、蝉知安装会报错? 之理解MySQL的SQL_MODE

    最近用蝉知的CMS 建站比较多,感觉蛮顺手的,但在给客户安装的时候却会出现安装报错,其原因也很简单 查看了一下他们的install.sql文件中,有些时间字段的默认值是0000-00-00 00:00 ...

  8. mysql 从聚合函数group by到sql_mode

    说到group by, 想必大家都不陌生, 就是对查询的数据进行分组,我们可以通过该操作实现一些特殊需求,比如去重. 最近在项目中使用HQL:" from TSjrz where CBh = ...

  9. MySQL的SQL_Mode修改小计

    问题复现 今天突然发现MySQL服务器升级之后sql_mode变成宽松摸索了,危害如下: 临时解决 set global sql_mode='strict_trans_tables'(阿里服务器默认是 ...

随机推荐

  1. EfCore基本用法

    db first 和 code first的基本使用方法 https://www.cnblogs.com/Starts_2000/p/mysql-efcore20-codefirst-dbfirst- ...

  2. FreeRTOS 移植

    添加FreeRTOS源码到工程中 在工程源码中创建FreeRTOS目录存放拷贝的文件 拷贝FreeRTOS->Source中的文件 可将其他不需要的文件夹全部删掉,只留3个 拷贝Demo中Fre ...

  3. bootstrap tab选项卡

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  4. 18C 新的发行版和补丁模型

    18C 新的发行版和补丁模型 以后不再会有第一和第二个发行版,如12.1,12.2,以后只有18C,19C,20C 这样的发行版. 更少的One-Off 补丁 澄清1:版本家族 从生命周期支持上来说1 ...

  5. 【DevOps】在CentOS中安装Rancher2,并配置kubernetes集群

    准备 一台CentOS主机,安装DockerCE,用于安装Rancher2 一台CentOS主机,安装DockerCE,用于安装kubernetes集群管理主机 多台CentOS主机,安装Docker ...

  6. VMware14虚拟机与宿主机建立通讯

    当我们在VMware14中运行虚拟机搭建实验环境就需要与我们的宿主机或另一台虚拟机连接通讯,下面我们就来看看如何建立通讯,实现虚拟机与宿主机.虚拟机与虚拟机互联互通. 准备环境:一台安装好VMware ...

  7. CMake---基础练习1

    因为卡在一个问题上,几经排除应该可能是CMakeLists.txt写的不正确,但是又生成了可执行文件,运行可执行文件报错.多方排除,应该是CMakeLists.txt加载动态库的时候,函数加载的不全. ...

  8. SASS 和 LESS 的区别

    1.编译环境不同 SASS 的安装需要 Ruby 环境,是在服务端处理的: LESS 需要引入 less.js 来处理代码输出 CSS 到浏览器,也可以在开发环节使用 LESS,然后编译成 CSS 文 ...

  9. 【记忆化搜索】[NOIP-2017--普及组] -- 棋盘

    [题目描述] 原题目链接地址:   有一个m × m的棋盘,棋盘上每一个格子可能是红色.黄色或没有任何颜色的.你现在要从棋盘的最左上角走到棋盘的最右下角. 任何一个时刻,你所站在的位置必须是有颜色的( ...

  10. 如何在linux系统下查看日志

    在linux系统下, 首先在idea中使用clean---->install----->package将这个项目进行打包,打包的方式 , 根据你在项目中的pom文件,最上面,可以查看到 这 ...