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

MySQL存储过程OUT值获取失败:PDO调用出现fetch()错误求助

问题分析与解决方案

核心问题梳理

你遇到的错误Call to a member function fetch() on bool本质是第二个query()执行失败返回了false,根源出在存储过程语法错误、参数赋值错误,以及PHP处理存储过程的方式不当这三个方面。


1. 修正存储过程的语法与参数问题

你的存储过程存在两处关键错误:

  • IF EXISTS语句缺少闭合括号,导致语法报错;
  • 错误使用会话变量@returnValue而非定义的OUT参数returnValue,导致返回值无法正确传递。

修正后的存储过程代码:

DELIMITER $$
CREATE DEFINER=`lvcs_ukpi`@`localhost` PROCEDURE `Login`(IN `param_login` VARCHAR(30), IN `param_senha` VARCHAR(30), OUT `returnValue` INT)
    NO SQL
BEGIN
    -- 修正IF EXISTS的闭合括号,统一字段名(注意原代码混用了password和senha,这里以senha为准)
    IF EXISTS(SELECT * FROM Users
               WHERE LOWER(login) = LOWER(param_login)
                 AND senha = param_senha) THEN

        SELECT *
          FROM Users
         WHERE login = param_login
           AND senha = param_senha;

         SET returnValue = 0; -- 直接使用定义的OUT参数,而非会话变量@returnValue

    ELSE
        SET returnValue = -999;
    END IF;

END$$
DELIMITER ;

2. 修正PHP代码的错误处理逻辑

原PHP代码存在SQL注入风险,且未正确处理存储过程的多结果集,导致连接状态异常。以下是安全且正确的实现:

// 使用PDO预处理语句避免SQL注入
$stmt = $conn->prepare("CALL Login(:login, :senha, @returnValue)");
$stmt->bindParam(':login', $login, PDO::PARAM_STR);
$stmt->bindParam(':senha', $senha, PDO::PARAM_STR);

// 执行存储过程
$stmt->execute();

// 读取登录成功时返回的用户信息
$userInfo = null;
if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $userInfo = $row;
}

// 必须消耗所有剩余结果集,否则连接会处于锁定状态
while ($stmt->nextRowset()) {
    // 无需处理,仅用于清空结果集队列
}

// 获取OUT参数的返回值
$stmt = $conn->prepare("SELECT @returnValue AS returnValue");
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$valor = $result['returnValue'];

// 后续业务逻辑
if ($valor === 0) {
    echo "登录成功!用户信息:" . print_r($userInfo, true);
} else {
    echo "登录失败,错误码:" . $valor;
}

错误原因详解

  1. 存储过程语法错误:IF EXISTS(...)的条件括号未闭合,导致存储过程执行失败,PHP调用时第一个query()返回false,后续连接状态异常,第二个query()也返回false,最终调用fetch()时触发错误。
  2. 参数赋值错误:存储过程中用@returnValue(会话变量)代替了定义的OUT参数returnValue,导致返回值无法正确传递到外部。
  3. 未处理多结果集:存储过程执行时会先返回用户信息的结果集,若不消耗这个结果集就直接执行后续查询,PDO连接会处于未就绪状态,导致后续查询失败。

内容的提问来源于stack exchange,提问作者Libania Paes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 07:50:12