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 8.0.24 安装配置方法图文教程
May 12 MySQL
详解MySQL的Seconds_Behind_Master
May 18 MySQL
MySQL 8.0 Online DDL快速加列的相关总结
Jun 02 MySQL
MySQL系列之八 MySQL服务器变量
Jul 02 MySQL
SQL实现LeetCode(178.分数排行)
Aug 04 MySQL
MySQL数据库优化之通过索引解决SQL性能问题
Apr 10 MySQL
mysql 乱码 字符集latin1转UTF8
Apr 19 MySQL
MySQL如何使备份得数据保持一致
May 02 MySQL
MySQL GTID复制的具体使用
May 20 MySQL
MySQL中正则表达式(REGEXP)使用详解
Jul 07 MySQL
MySQL的表级锁,行级锁,排它锁和共享锁
Jul 15 MySQL
MySQL池化框架学习接池自定义
Jul 23 MySQL
一篇文章弄懂MySQL查询语句的执行过程
详解MySQL主从复制及读写分离
MySQL 表空间碎片的概念及相关问题解决
MySQL kill不掉线程的原因
May 07 #MySQL
MySQL数字类型自增的坑
May 07 #MySQL
MySQL获取所有分类的前N条记录
May 07 #MySQL
教你解决往mysql数据库中存入汉字报错的方法
You might like
用PHP实现多服务器共享SESSION数据的方法
2007/03/16 PHP
ThinkPHP快速入门实例教程之数据分页
2014/07/01 PHP
thinkPHP实现瀑布流的方法
2014/11/29 PHP
yii2 页面底部加载css和js的技巧
2016/04/21 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
漂亮的jquery提示效果(仿腾讯弹出层)
2013/02/05 Javascript
在JavaScript中typeof的用途介绍
2013/04/11 Javascript
js获取上传文件大小示例代码
2014/04/10 Javascript
网页右侧悬浮滚动在线qq客服代码示例
2014/04/28 Javascript
七个很有意思的PHP函数
2014/05/12 Javascript
windows8.1+iis8.5下安装node.js开发环境
2014/12/12 Javascript
简单谈谈json跨域
2016/03/13 Javascript
AngularJS指令与指令之间的交互功能示例
2016/12/14 Javascript
原生JS中slice()方法和splice()区别
2017/03/06 Javascript
vue2.0 根据状态值进行样式的改变展示方法
2018/03/13 Javascript
Vue 实现双向绑定的四种方法
2018/03/16 Javascript
详解vue中组件参数
2018/07/09 Javascript
JavaScript canvas仿代码流瀑布
2020/02/10 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
2020/11/04 Javascript
python 输出一个两行字符的变量
2009/02/05 Python
python文件比较示例分享
2014/01/10 Python
Python partial函数原理及用法解析
2019/12/11 Python
tf.concat中axis的含义与使用详解
2020/02/07 Python
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
nohup的用法
2012/11/26 面试题
使用Vue.js和MJML创建响应式电子邮件
2021/03/23 Vue.js
机械制造与自动化应届生求职信
2013/11/16 职场文书
授权委托书(完整版)
2014/09/10 职场文书
要账委托书范本
2014/09/15 职场文书
个人公司授权委托书范本
2014/10/12 职场文书
2014年青年教师工作总结
2014/12/17 职场文书
小学优秀学生评语
2014/12/29 职场文书
初中体育课教学反思
2016/02/16 职场文书
利用js实现简单开关灯代码
2021/11/23 Javascript
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP
使用Redis实现分布式锁的方法
2022/06/16 Redis