MySQL sql_mode修改不生效的原因及解决


Posted in MySQL onMay 07, 2021

前言

近期多次聊到sql_mode的话题,也是多次遇到相关问题,今天就趁热打铁,再给大家带来一个sql_mode的案例分享。

场景模拟

基于业务敏感性的考虑,下面涉及的表、存储过程等均非真实数据,但并不影响排查过程。

(1)客户侧开发童鞋创建了一个存储过程,该存储过程没有严格遵守group by标准语法

session 1:
mysql> delimiter //

mysql> create procedure test_for_group_by()
    -> begin
    -> select k,pad,count(*) from test.test group by k;
    -> end //
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;

(2)客户侧开发童鞋调用该存储过程,报错ERROR 1140;因为当时存储过程比较复杂,改造起来比较麻烦,所以客户侧选择修改sql_mode

session 1:
mysql> call test_for_group_by();
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'test.test.k'; this is incompatible with sql_mode=only_full_group_by

(3)客户侧修改完sql_mode,再次执行,发现仍然报错ERROR 1140

session 2:
mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected (0.00 sec)

session 1:
mysql> call test_for_group_by();
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'test.test.k'; this is incompatible with sql_mode=only_full_group_by

(4)此时想到,修改系统变量,只对新建连接有效,对已有连接不起作用;于是,让客户侧重新建立连接,确认系统变量已生效,再次调用存储过程,但仍然报错ERROR 1140,重复尝试几次都是这个结果

session 3:
mysql> show variables like 'sql_mode';
+---------------+------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                  |
+---------------+------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> call test_for_group_by();
ERROR 1140 (42000): In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'test.test.k'; this is incompatible with sql_mode=only_full_group_by

(5)进一步排查,让客户侧在该会话,执行非标准的group by语句,发现可以正常执行

session 3:
mysql> select user,host,count(*) From mysql.user group by user;
+---------------+-----------+----------+
| user          | host      | count(*) |
+---------------+-----------+----------+
| mysql.session | localhost |        1 |
| mysql.sys     | localhost |        1 |
| root          | localhost |        1 |
| rpl_user      | %         |        1 |
| test          | %         |        1 |
+---------------+-----------+----------+
5 rows in set (0.00 sec)

(6)继续排查发现,该存储过程的sql_mode,还是包括ONLY_FULL_GROUP_BY,因此执行报错

session 2:
mysql> select routine_catalog,routine_schema,routine_name,routine_type,created,last_altered,sql_mode from routines where routine_name='test_for_group_by';
+-----------------+----------------+-------------------+--------------+---------------------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| routine_catalog | routine_schema | routine_name      | routine_type | created             | last_altered        | sql_mode                                                                                                                                  |
+-----------------+----------------+-------------------+--------------+---------------------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| def             | test           | test_for_group_by | PROCEDURE    | 2020-12-24 12:12:10 | 2020-12-24 12:12:10 | 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 |
+-----------------+----------------+-------------------+--------------+---------------------+---------------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

(7)这里我们也可以知道,系统变量修改只对新建对象有效,对已有对象不生效;解决办法很简单,重建该存储过程即可

session 3:
mysql> drop procedure test_for_group_by;
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter //

mysql> create procedure test_for_group_by()
    -> begin
    -> select k,pad,count(*) from test.test group by k;
    -> end //
Query OK, 0 rows affected (0.01 sec)

mysql> delimiter ;

mysql> call test_for_group_by();
+--------+-------------------------------------------------------------+----------+
| k      | pad                                                         | count(*) |
+--------+-------------------------------------------------------------+----------+
| 393975 | 35227182905-15234265621-59793845249-15413569710-23749555118 |        1 |
| 495688 | 09512147864-77936258834-40901700703-13541171421-15205431759 |        1 |
| 497896 | 13152283289-69561545685-52868757241-04245213425-69280254356 |        1 |
| 498573 | 43131080328-59298106536-35954612339-97546855884-75769514803 |        1 |
| 500775 | 27590239742-20204899609-34345212327-79811525340-24267764271 |        1 |
| 501885 | 63188288836-92351140030-06390587585-66802097351-49282961843 |        1 |
| 503330 | 01495266405-82925129145-92643983850-90243995398-18709399387 |        1 |
| 503666 | 40929980986-33813039690-13155419391-97985458477-39771362212 |        1 |
| 504353 | 00505722282-72931248925-57037623248-81117963809-88658076981 |        1 |
| 514246 | 21979564480-87492594656-60524686334-78820761788-57684966682 |        1 |
+--------+-------------------------------------------------------------+----------+
10 rows in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

总结

通过这个案例,我们可以知道,修改sql_mode系统变量,只对新建连接和新建对象(主要包括函数和存储过程)有效,对已有连接和已有对象不生效。

以上就是MySQL sql_mode修改不生效的原因及解决的详细内容,更多关于MySQL sql_mode修改不生效的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
MySQL基础(二)
Apr 05 MySQL
mysql知识点整理
Apr 05 MySQL
mysql优化
Apr 06 MySQL
Mysql 用户权限管理实现
May 25 MySQL
Navicat for MySQL的使用教程详解
May 27 MySQL
Mysql 如何查询时间段交集
Jun 08 MySQL
mysql 如何获取两个集合的交集/差集/并集
Jun 08 MySQL
MySQL8.0的WITH查询详情
Aug 30 MySQL
Mysql存储过程、触发器、事件调度器使用入门指南
Jan 22 MySQL
Mysql分析设计表主键为何不用uuid
Mar 31 MySQL
MySQL Server 层四个日志
Mar 31 MySQL
优化Mysql查询的示例
Apr 26 MySQL
一篇文章弄懂MySQL查询语句的执行过程
详解MySQL主从复制及读写分离
MySQL 表空间碎片的概念及相关问题解决
MySQL kill不掉线程的原因
May 07 #MySQL
MySQL数字类型自增的坑
May 07 #MySQL
MySQL获取所有分类的前N条记录
May 07 #MySQL
教你解决往mysql数据库中存入汉字报错的方法
You might like
在Mac OS上编译安装Nginx+PHP+MariaDB开发环境的教程
2016/02/23 PHP
Zend Framework教程之Loader以及PluginLoader用法详解
2016/03/09 PHP
Yii实现复选框批量操作实例代码
2017/03/15 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
对象无length属性时IE6/IE7中无法将其转换成伪数组(ArrayLike)
2011/07/31 Javascript
设为首页加入收藏兼容360/火狐/谷歌/IE等主流浏览器的代码
2013/03/26 Javascript
get(0).tagName获得作用标签示例代码
2014/10/08 Javascript
jQuery中DOM树操作之复制元素的方法
2015/01/23 Javascript
简单纯js实现点击切换TAB标签实例
2015/08/23 Javascript
React学习之事件绑定的几种方法对比
2017/09/24 Javascript
vue-cli3使用 DllPlugin 实现预编译提升构建速度
2019/04/24 Javascript
深度了解vue.js中hooks的相关知识
2019/06/14 Javascript
简单使用webpack打包文件的实现
2019/10/29 Javascript
在vue中使用回调函数,this调用无效的解决
2020/08/11 Javascript
浅析JavaScript预编译和暗示全局变量
2020/09/03 Javascript
nuxt 页面路由配置,主页轮播组件开发操作
2020/11/05 Javascript
Python 代码性能优化技巧分享
2012/08/07 Python
python 排列组合之itertools
2013/03/20 Python
Python爬取十篇新闻统计TF-IDF
2018/01/03 Python
python样条插值的实现代码
2018/12/17 Python
Python控制键盘鼠标pynput的详细用法
2019/01/28 Python
详解Django中CBV(Class Base Views)模型源码分析
2019/02/25 Python
对python 中re.sub,replace(),strip()的区别详解
2019/07/22 Python
PyCharm导入python项目并配置虚拟环境的教程详解
2019/10/13 Python
django序列化serializers过程解析
2019/12/14 Python
Python IDLE或shell中切换路径的操作
2020/03/09 Python
Myprotein蛋白粉美国官网:欧洲畅销运动营养品牌
2016/11/15 全球购物
VC++笔试题
2014/10/13 面试题
资产评估专业大学生求职信
2013/09/29 职场文书
少先队入队活动方案
2014/02/08 职场文书
《生命的药方》教学反思
2014/04/08 职场文书
经济管理自荐书
2014/06/09 职场文书
优秀大学生自荐信
2014/06/09 职场文书
2014年公务员转正工作总结
2014/11/07 职场文书
高一军训决心书
2015/02/05 职场文书
毕业生捐书活动倡议书
2015/04/27 职场文书