Knex查询MySQL存储过程结果与Workbench不一致如何解决
问题根因
你遇到的结果不一致问题是存储过程多结果集返回规则差异导致的:
- MySQL Workbench 执行存储过程时默认只展示最后一个 SELECT 语句的结果
- Knex 底层依赖 mysql2 驱动,调用存储过程时会按顺序返回所有 SELECT 语句产生的全部结果集
你的存储过程里共有3条SELECT语句:前2条是给变量赋值的查询,第3条才是你需要的业务状态返回,你当前代码取result[0][0]拿到的是第一条赋值查询的结果,自然和Workbench展示的不一致。
解决方案
方案1:修改存储过程(推荐)
将前2条赋值类SELECT改成SELECT ... INTO语法,不会生成额外结果集,同时建议改用存储过程局部变量避免连接池会话变量污染。
修改后的存储过程代码:
CREATE DEFINER=`root`@`localhost` PROCEDURE `leaveClan`(in userId int) BEGIN -- 声明局部变量,避免会话变量污染 DECLARE rights INT DEFAULT 0; DECLARE clanId INT DEFAULT 0; DECLARE members INT DEFAULT 0; -- 赋值改用INTO,不生成结果集 SELECT `right`, clans_id INTO rights, clanId FROM clans_members WHERE accounts_id = userId LIMIT 1; SELECT count(*) INTO members FROM clans_members WHERE clans_members.clans_id = clanId; IF rights = 3 AND members > 1 THEN SELECT 'not-leave-full-clan' as 'error'; ELSE DELETE FROM `senpa`.`clans_members` WHERE accounts_id = userId; IF members = 1 THEN DELETE FROM `senpa`.`clans` WHERE id = clanId; END IF; SELECT 'clans-start-show' as 'success'; END IF; END
修改后你的原有Knex调用代码不需要改动,就能拿到正确的业务返回结果。
方案2:不修改存储过程,调整Knex取值逻辑
直接取返回结果集的最后一项即可:
const leaveClan = async function(userId) { const result = await db.raw('call senpa.`leaveClan`(?);', [userId]); // 取最后一个结果集的第一条数据,就是你需要的业务状态 const targetResult = result[0].at(-1)[0]; // Node.js版本低于16.6.0不支持at()方法时替换为:result[0][result[0].length - 1][0] console.log(targetResult) return targetResult; } leaveClan(1);
内容的提问来源于stack exchange,提问作者TopoR
相关产品推荐
相关产品推荐

