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

PHP读取MySQL存储过程第二个结果集绑定变量报错求助

解决PHP调用MySQL存储过程读取第二个结果集时bind_result报错的问题

碰到这种情况我太熟悉了!问题出在你切换结果集后,直接调用mysqli_stmt_bind_result时,语句句柄还保留着第一个结果集的元数据,导致绑定的变量数和第二个结果集的字段数不匹配。咱们来一步步解决这个问题:

核心原因

当你执行mysqli_stmt_next_result($call)切换到第二个结果集后,原来的语句句柄并没有自动更新结果集的字段信息。这时候再用mysqli_stmt_bind_result,它还是按照第一个结果集的9个字段来匹配,而第二个结果集只有3个字段,自然就报“变量数不匹配”的错了。

推荐解决方案:用mysqli_stmt_get_result处理多结果集

相比直接绑定结果,mysqli_stmt_get_result会返回一个标准的结果集对象,能清晰处理每个结果集,代码也更易维护。修改后的代码如下:

public function GetSession($sessionId) { 
    $conn = mysqli_connect(DbConstants::$servername, DbConstants::$username, DbConstants::$password, DbConstants::$dbname); 
    if ($conn->connect_error) { 
        die("Connection failed: " . $conn->connect_error); 
    } 

    $call = mysqli_prepare($conn, 'CALL Sp_Session_GetById(?)'); 
    mysqli_stmt_bind_param($call, 'i', $sessionId); 
    mysqli_stmt_execute($call); 

    // 处理第一个结果集:获取Session基础数据
    $sessionResult = mysqli_stmt_get_result($call);
    $sessionRow = mysqli_fetch_assoc($sessionResult);
    $session = new Session(
        $sessionRow['id'],
        $sessionRow['startTime'],
        $sessionRow['duration'],
        $sessionRow['description'],
        $sessionRow['instructor_id'],
        $sessionRow['aircraft_id'],
        $sessionRow['display'],
        $sessionRow['bookable'],
        $sessionRow['cancelled'],
        []
    );

    // 处理第二个结果集:获取关联的sessiontype数据
    if(mysqli_stmt_more_results($call)) { 
        mysqli_stmt_next_result($call); 
        $sessionTypeResult = mysqli_stmt_get_result($call);
        $sessionTypes = [];
        // 循环读取所有行
        while ($row = mysqli_fetch_assoc($sessionTypeResult)) {
            $sessionTypes[] = [
                'sessiontype_id' => $row['sessiontype_id'],
                'spaces' => $row['spaces'],
                'enabled' => $row['enabled']
            ];
        }
        // 将数据赋值给Session对象(假设类中有对应的属性)
        $session->sessionTypes = $sessionTypes;
    } 

    // 清理资源
    mysqli_free_result($sessionResult);
    if(isset($sessionTypeResult)) mysqli_free_result($sessionTypeResult);
    mysqli_stmt_close($call);
    mysqli_close($conn);

    return $session;
}

注意事项

  • 这个方法需要你的PHP环境安装了mysqlnd驱动(大部分现代PHP环境默认都有),如果没有的话,你需要先启用它。
  • 别忘了在最后清理结果集和数据库连接,避免资源泄漏。

备选方案(无mysqlnd时)

如果实在无法使用mysqlnd,你需要在切换结果集后重新存储结果、获取字段数,再动态绑定变量。这种方式比较繁琐,示例如下(只展示关键部分):

// 切换到第二个结果集后
mysqli_stmt_store_result($call);
$fieldCount = mysqli_stmt_num_fields($call);
// 动态创建绑定变量
$vars = [];
for ($i = 0; $i < $fieldCount; $i++) {
    $vars[] = &${"var_$i"};
}
call_user_func_array('mysqli_stmt_bind_result', array_merge([$call], $vars));

// 然后循环读取
$sessionTypes = [];
while(mysqli_stmt_fetch($call)) {
    $sessionTypes[] = [
        'sessiontype_id' => $var_0,
        'spaces' => $var_1,
        'enabled' => $var_2
    ];
}

不过还是强烈推荐用第一种方法,代码更简洁不易出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:02:02