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 update set 和 and的区别
May 08 MySQL
MySQL 重写查询语句的三种策略
May 10 MySQL
.Net Core导入千万级数据至Mysql的步骤
May 24 MySQL
MySQL查看表和清空表的常用命令总结
May 26 MySQL
MySQL下使用Inplace和Online方式创建索引的教程
May 26 MySQL
MySQL8.0无法启动3534的解决方法
Jun 03 MySQL
MySQL 不等于的三种使用及区别
Jun 03 MySQL
Mysql中调试存储过程最简单的方法
Jun 30 MySQL
Mysql8.0递归查询的简单用法示例
Aug 04 MySQL
SQL 聚合、分组和排序
Nov 11 MySQL
分享mysql的current_timestamp小坑及解决
Nov 27 MySQL
详细介绍MySQL中limit和offset的用法
May 06 MySQL
一篇文章弄懂MySQL查询语句的执行过程
详解MySQL主从复制及读写分离
MySQL 表空间碎片的概念及相关问题解决
MySQL kill不掉线程的原因
May 07 #MySQL
MySQL数字类型自增的坑
May 07 #MySQL
MySQL获取所有分类的前N条记录
May 07 #MySQL
教你解决往mysql数据库中存入汉字报错的方法
You might like
ThinkPHP采用模块和操作分析
2011/04/18 PHP
php+ajax实时输入自动搜索匹配的方法
2014/12/26 PHP
详解PHP匿名函数与注意事项
2016/03/29 PHP
使用ucenter实现多站点同步登录的讲解
2019/03/21 PHP
通过pjax实现无刷新翻页(兼容新版jquery)
2014/01/31 Javascript
node.js操作mongoDB数据库示例分享
2014/11/26 Javascript
jQuery中:animated选择器用法实例
2014/12/29 Javascript
JS未跨域操作iframe里的DOM
2016/06/01 Javascript
使用 bootstrap modal遇到的问题小结
2016/11/09 Javascript
vue全局组件与局部组件使用方法详解
2018/03/29 Javascript
JavaScript创建对象方法实例小结
2018/09/03 Javascript
在vue里使用codemirror遇到的问题
2018/11/01 Javascript
从零到一详聊创建Vue工程及遇到的常见问题
2019/04/25 Javascript
Nuxt v-bind绑定img src不显示的解决
2019/12/05 Javascript
[05:39]2014DOTA2国际邀请赛 DK晋级胜者组专访战队国士无双
2014/07/14 DOTA
[33:33]完美世界DOTA2联赛PWL S2 FTD.C vs SZ 第二场 11.27
2020/11/30 DOTA
Tornado Web服务器多进程启动的2个方法
2014/08/04 Python
详解Django缓存处理中Vary头部的使用
2015/07/24 Python
微信跳一跳python辅助脚本(总结)
2018/01/11 Python
Python类的继承用法示例
2019/01/31 Python
python调用c++传递数组的实例
2019/02/13 Python
Python3enumrate和range对比及示例详解
2019/07/13 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
PyCharm Anaconda配置PyQt5开发环境及创建项目的教程详解
2020/03/24 Python
Python实现的北京积分落户数据分析示例
2020/03/27 Python
一款css实现的鼠标经过按钮的特效
2014/09/11 HTML / CSS
viagogo波兰票务平台:演唱会、体育比赛、戏剧门票
2018/04/23 全球购物
华纳兄弟工作室的官方授权商店:WB Shop
2018/11/30 全球购物
综合素质的自我鉴定
2013/10/07 职场文书
简历上的自我评价
2014/02/03 职场文书
《湘夫人》教学反思
2014/02/21 职场文书
春节联欢晚会主持词范文
2014/03/24 职场文书
代办委托书怎样写
2014/04/08 职场文书
2014年党的群众路线教育实践活动总结
2014/04/25 职场文书
乡镇群众路线专项整治方案
2014/11/03 职场文书
信息技术教研组工作总结
2015/08/13 职场文书