如何在Laravel中获取MySQL存储过程的输出参数数据?
在Laravel中获取MySQL存储过程输出参数的正确方法
问题原因
你用DB::select()调用存储过程时,只会返回存储过程中直接执行的SELECT语句结果(也就是你写的SELECT concat('retCount is ', retCount);那一行),而存储过程的OUT参数是赋值给MySQL会话变量(@returnCount、@totalUsersCount)的,不会自动返回,必须单独查询这些会话变量才能拿到值。
解决方案1:使用DB门面分两步操作
先调用存储过程,再查询会话变量获取输出参数:
// 第一步:调用存储过程,执行后输出参数会存入MySQL会话变量 DB::statement("call getObjectsCount('users_without_completed_tasks', @returnCount, @totalUsersCount)"); // 第二步:查询会话变量,获取输出参数值 $output = DB::select("SELECT @returnCount AS retCount, @totalUsersCount AS totalUsersCount")[0]; // 提取数据使用 $retCount = $output->retCount; $totalUsersCount = $output->totalUsersCount; dd($retCount, $totalUsersCount);
解决方案2:使用PDO原生操作(适合多结果集场景)
如果存储过程中包含多个SELECT语句(比如你当前的调试用SELECT),需要先遍历所有结果集,再查询会话变量:
// 获取PDO连接实例 $pdo = DB::connection()->getPdo(); // 准备并执行存储过程调用 $stmt = $pdo->prepare("CALL getObjectsCount(:objectType, @returnCount, @totalUsersCount)"); $stmt->bindParam(':objectType', 'users_without_completed_tasks', PDO::PARAM_STR); $stmt->execute(); // 遍历并跳过所有存储过程产生的结果集 do { $stmt->fetchAll(); } while ($stmt->nextRowset()); // 查询会话变量获取输出参数 $result = $pdo->query("SELECT @returnCount AS retCount, @totalUsersCount AS totalUsersCount")->fetch(PDO::FETCH_OBJ); dd($result->retCount, $result->totalUsersCount);
额外优化建议
可以去掉存储过程中用于调试的SELECT concat('retCount is ', retCount);语句,避免不必要的结果集处理,让存储过程只专注于赋值输出参数:
DELIMITER $$ DROP PROCEDURE IF EXISTS getObjectsCount $$ CREATE DEFINER=`lardev`@`localhost` PROCEDURE `getObjectsCount`( IN in_objectType varchar(100), OUT retCount bigint unsigned, OUT totalUsersCount bigint unsigned ) BEGIN IF in_objectType = 'users_without_active_tasks' THEN select count(*) into retCount from users where users.id not in (select distinct tasks.creator_id from tasks where tasks.status = 'T'); END IF; IF in_objectType = 'users_without_completed_tasks' THEN select count(*) into retCount from users where users.id not in (select distinct tasks.creator_id from tasks where tasks.status = 'D'); END IF; select count(*) into totalUsersCount from users; END$$ DELIMITER ;
内容的提问来源于stack exchange,提问作者Petro Gromovo
相关产品推荐
相关产品推荐

