
群里有位大佬遇到个问题: 执行存储过程时,报错:"can’t return a result set in the given context"
大概长这样:

从描述来看是: 在给定的上下文中不能返回结果集.
在日常使用中, 难免会遇到类似的这种报错, 此时我们就需要一种通用的方法来帮我们定位问题.
通常这种报错都有报错码, 比如"MY-001312"之类的(有的驱动可能会把报错码屏蔽/转换掉,就离谱).
我们可以根据报错内容去源码的"share/messages_to_clients.txt"中查看报错关键字ER_SP_BADSELECT

然后我们就可以根据关键字(ER_SP_BADSELECT)去源码里面找到相关的逻辑了.
grep -r ER_SP_BADSELECT sql/
通常sql处理相关的在sql目录, innodb存储相关的在storage/innobase. 不清楚的话, 就整个源码目录搜索吧(建议排除掉test之类的目录, 毕竟那里面大部分报错码都有...)
本次我们运气好, 只有一个地方sql/sql_call.cc包含报错关键字, 有很多报错都会存在于多个地方.
既然已经找到报错的源码了, 接下来就是分析逻辑了; 有编程基础的话, 看个大概就能知道逻辑了, 如果没得编程基础的话, 可以交给AI.
if (!thd->get_protocol()->has_client_capability(CLIENT_MULTI_RESULTS)) {
// Client does not support multiple result sets
my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
return true;
}
本次的触发逻辑也比较简单, 就是客户端连接时候设置的Capabilities Flags没有CLIENT_MULTI_RESULTS就报错ER_SP_BADSELECT
既然我们已经知道了原因: client_capability没有CLIENT_MULTI_RESULTS, 那我们就模拟验证下. 不同的驱动设置client_capability的方法可能不同, 所以这次我们使用自己编写的驱动(https://github.com/ddcw/ddcw/tree/master/python/minipymysql)来验证. 需要稍微修改下:
self.client_flag = 33531525 if 'client_flag' not in kwargs else int(kwargs['client_flag']) 方便我们设置client_flag
client_flag = self.client_flag 启用我们设置的client_flag
然后使用类似如下连接(参考的pymysql)验证即可:
-- 创建测试的存储过程
create table db1.t20260112(id int, name varchar(200));
insert into db1.t20260112 values(1,'ddcw');
delimiter //
create procedure pro_select_table_rows( IN rows1 int)
begin
select * from db1.t20260112 limit rows1;
end//
delimiter ;# 使用如下python代码验证
# 正常情况(含CLIENT_MULTI_RESULTS)下调用存储过程
import pymysql
conn = pymysql.connect(
host='192.168.101.21',
port=3314,
user='root',
password='123456',
)
cursor = conn.cursor()
cursor.execute('call db1.pro_select_table_rows(1)')
cursor.fetchall()
# 异常情况下(去掉CLIENT_MULTI_RESULTS)调用存储过程
import pymysql
conn = pymysql.connect(
host='192.168.101.21',
port=3314,
user='root',
password='123456',
client_flag=33531525-(2**17),
)
cursor = conn.cursor()
cursor.execute('call db1.pro_select_table_rows(1)')
cursor.fetchall()
我们发现去掉CLIENT_MULTI_RESULTS之后确实会报错"can't return a result set in the given context", 说明我们分析得没毛病!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。