如何在MySQL存储过程中返回合并后的多行结果?
MySQL存储过程合并多结果集为单表返回方案
你的思路完全可行,通过创建临时表收集游标循环中所有查询的结果,最后一次性返回临时表数据,就能解决后端需要处理多个结果集的问题。针对你的MySQL 8.0.20版本,修改后的存储过程代码如下:
DELIMITER $$ CREATE DEFINER=`administrator`@`localhost` PROCEDURE `lending_ewallets_balance_in_merchant`(IN `user_id_param` BIGINT UNSIGNED, IN `business_id_param` INT UNSIGNED) NO SQL BEGIN DECLARE dossier_id INT; DECLARE query_string VARCHAR(255) DEFAULT ''; DECLARE cursor_List_isdone BOOLEAN DEFAULT FALSE; -- 创建临时表,字段结构与查询返回结果匹配 CREATE TEMPORARY TABLE IF NOT EXISTS temp_balances ( lending_dossier_id INT, type VARCHAR(50), -- 根据lending_users_dossiers表type字段实际类型调整长度 balance DECIMAL(18,2) -- 根据lending_ewallet_transactions.credit字段类型调整精度 ); DECLARE user_dossiers CURSOR FOR Select ld.id, lwp.query_string FROM lending_users_dossiers ld JOIN lending_where_to_pays lwp ON ld.lending_where_to_pay_id = lwp.id WHERE user_id = user_id_param AND (ld.status = 'activated' OR ld.status = 'finished'); # 'finished' is for loans DECLARE CONTINUE HANDLER FOR NOT FOUND SET cursor_List_isdone = TRUE; Open user_dossiers; loop_List: LOOP FETCH user_dossiers INTO dossier_id, query_string; IF cursor_List_isdone THEN LEAVE loop_List; END IF; SET @qry = CONCAT( "INSERT INTO temp_balances(lending_dossier_id, type, balance) SELECT ld.id lending_dossier_id, ld.type, SUM(let.credit) balance FROM lending_users_dossiers ld JOIN lending_ewallet_transactions let ON ld.id = let.lending_dossier_id WHERE ld.id = ", dossier_id, " AND ", business_id_param, " IN(", query_string, ")", "GROUP BY ld.id, ld.type"); PREPARE stmt FROM @qry; EXECUTE stmt; DEALLOCATE PREPARE stmt; END LOOP loop_List; Close user_dossiers; -- 返回所有合并后的结果 SELECT * FROM temp_balances; -- 可选:手动清理临时表,MySQL会话结束后会自动删除临时表 DROP TEMPORARY TABLE IF EXISTS temp_balances; END$$ DELIMITER ;
关键修改说明:
- 在存储过程开头创建临时表
temp_balances,字段结构与原查询返回的lending_dossier_id、type、balance完全对应 - 将原循环中直接执行查询返回结果的逻辑,改为插入临时表
- 游标循环结束后,通过
SELECT * FROM temp_balances一次性返回所有结果 - 可选添加临时表删除语句,避免会话内重复调用存储过程时的表已存在错误
注意事项:
- 请根据实际表结构调整临时表的字段类型(比如
type的长度、balance的小数精度),确保与查询结果类型一致 - 临时表仅在当前数据库会话中可见,不会与其他会话产生数据冲突
- 若循环中的某条查询无返回结果,不会向临时表插入空行,最终结果仅包含有效数据
内容的提问来源于stack exchange,提问作者Martin AJ
相关产品推荐
相关产品推荐

