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官方导出工具mysqlpump的使用
May 21 MySQL
MySQL快速插入一亿测试数据
Jun 23 MySQL
解决mysql的int型主键自增问题
Jul 15 MySQL
SQL之各种join小结详细讲解
Aug 04 MySQL
浅谈MySQL之select优化方案
Aug 07 MySQL
MySQL数据库10秒内插入百万条数据的实现
Nov 01 MySQL
一文简单了解MySQL前缀索引
Apr 03 MySQL
MySQL事务操作的四大特性以及并发事务问题
Apr 12 MySQL
MySQL时区造成时差问题
Apr 13 MySQL
提高系统的吞吐量解决数据库重复写入问题
Apr 23 MySQL
MySQL数据库实验之 触发器和存储过程
Jun 21 MySQL
Mysql中的触发器定义及语法介绍
Jun 25 MySQL
一篇文章弄懂MySQL查询语句的执行过程
详解MySQL主从复制及读写分离
MySQL 表空间碎片的概念及相关问题解决
MySQL kill不掉线程的原因
May 07 #MySQL
MySQL数字类型自增的坑
May 07 #MySQL
MySQL获取所有分类的前N条记录
May 07 #MySQL
教你解决往mysql数据库中存入汉字报错的方法
You might like
php cookie 作用范围?不要在当前页面使用你的cookie
2009/03/24 PHP
JS Replace()的高级使用方法介绍
2013/06/29 Javascript
CSS或者JS实现鼠标悬停显示另一元素
2016/01/22 Javascript
JavaScript资源预加载组件和滑屏组件的使用推荐
2016/03/10 Javascript
深入理解JQuery中的事件与动画
2016/05/18 Javascript
vue.js入门教程之绑定class和style样式
2016/09/02 Javascript
图片懒加载插件实例分享(含解析)
2017/01/09 Javascript
解决bootstrap中使用modal加载kindeditor时弹出层文本框不能输入的问题
2017/06/05 Javascript
Vue2.0 多 Tab切换组件的封装实例
2017/07/28 Javascript
详解wow.js中各种特效对应的类名
2017/09/13 Javascript
vuejs实现标签选项卡动态更改css样式的方法
2018/05/31 Javascript
Vue实现双向绑定的原理以及响应式数据的方法
2018/07/02 Javascript
详解webpack2异步加载套路
2018/09/14 Javascript
Vue+Django项目部署详解
2019/05/30 Javascript
nodejs文件夹深层复制功能
2019/09/03 NodeJs
Vue分页插件的前后端配置与使用
2019/10/09 Javascript
JavaScript事件委托实现原理及优点进行
2020/08/29 Javascript
用实例分析Python中method的参数传递过程
2015/04/02 Python
用Python创建声明性迷你语言的教程
2015/04/13 Python
Python中的with语句与上下文管理器学习总结
2016/06/28 Python
pycharm中连接mysql数据库的步骤详解
2017/05/02 Python
Python实现手写一个类似django的web框架示例
2018/07/20 Python
解决PyCharm同目录下导入模块会报错的问题
2018/10/13 Python
Python利用多线程同步锁实现多窗口订票系统(推荐)
2019/12/22 Python
关于windows下Tensorflow和pytorch安装教程
2020/02/04 Python
pycharm实现在子类中添加一个父类没有的属性
2020/03/12 Python
Python常用扩展插件使用教程解析
2020/11/02 Python
浅析border-radius如何兼容IE
2016/04/19 HTML / CSS
阿联酋最好的手机、电子产品和家用电器网上商店:Eros Digital Home
2020/08/09 全球购物
自我评价的正确写法
2013/09/19 职场文书
市场营销毕业生自荐信
2013/11/23 职场文书
求职导师推荐信范文
2015/03/27 职场文书
大学新生入学感想
2015/08/07 职场文书
成人成长感言如何写?
2019/08/16 职场文书
导游词之广东佛山(南风古灶)
2019/09/24 职场文书
 Redis 串行生成顺序编码的方法实现
2022/04/03 Redis