You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:05:22