
本文详解如何使用 php(mysqli 扩展)正确调用含 select 语句的 mysql 存储过程,并直接获取其返回的结果集,无需额外定义 out 参数或游标——只需通过预处理语句执行并逐结果集遍历即可。
本文详解如何使用 php(mysqli 扩展)正确调用含 select 语句的 mysql 存储过程,并直接获取其返回的结果集,无需额外定义 out 参数或游标——只需通过预处理语句执行并逐结果集遍历即可。
在 MySQL 中,存储过程可通过 SELECT 语句隐式返回一个或多个结果集(result sets),这与普通查询行为一致。PHP 的 mysqli 扩展原生支持多结果集处理,因此无需修改存储过程逻辑(如添加 OUT 参数、RETURN 值或显式声明游标),也无需在 SQL 层面做任何特殊适配——只要过程内包含 SELECT,其结果就能被 PHP 安全、完整地读取。
✅ 正确调用方式:使用 mysqli_stmt + 多结果集循环
以下是一个完整可运行的示例:
<?php
$host = 'localhost';
$user = 'root';
$pass = '';
$db = 'testdb';
$mysqli = new mysqli($host, $user, $pass, $db);
if ($mysqli->connect_error) {
die("连接失败: " . $mysqli->connect_error);
}
// 假设已存在存储过程:DELIMITER $$ CREATE PROCEDURE GetUsers() BEGIN SELECT id, name FROM users; END$$
$stmt = $mysqli->prepare("CALL GetUsers()");
$stmt->execute();
// 关键:使用 get_result() 获取第一个结果集
$result = $stmt->get_result();
if ($result && $result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
echo "ID: {$row['id']}, Name: {$row['name']}\n";
}
}
// 若存储过程返回多个结果集(例如多个 SELECT),需用 multi_query + next_result 配合
// 但 prepare+execute 方式默认只暴露第一个结果集;如需全部,推荐改用 mysqli::multi_query(见下方说明)
$stmt->close();
$mysqli->close();
?>⚠️ 注意事项与常见误区
- 不要尝试用 OUT 参数“返回”整个结果集:OUT 参数仅适用于单值(如 INT、VARCHAR),无法承载表格数据。MySQL 存储过程的 SELECT 本身就是标准结果集输出机制。
- mysqli_query() 不适用于带结果集的 CALL:直接 mysqli_query($conn, "CALL GetUsers()") 会因未处理多结果而引发警告或丢失数据;务必使用 mysqli_stmt 或显式 multi_query 流程。
-
多结果集场景(进阶):若存储过程内含多个 SELECT(如 SELECT * FROM a; SELECT * FROM b;),则必须使用 mysqli::multi_query() 并配合 mysqli::next_result() 和 mysqli::use_result() 循环读取:
$mysqli->multi_query("CALL GetMultipleResults()"); do { if ($result = $mysqli->use_result()) { while ($row = $result->fetch_row()) { print_r($row); } $result->free(); } } while ($mysqli->next_result());
✅ 总结
调用返回结果集的 MySQL 存储过程,在 PHP 中最简洁、健壮的方式是:
① 使用 mysqli::prepare() + execute();
② 紧接着调用 get_result() 获取首个结果集;
③ 按常规方式遍历(fetch_assoc() / fetch_array() 等)。
整个过程完全复用原有查询逻辑,零侵入、零冗余——你不需要在存储过程中添加任何“适配 PHP”的代码,MySQL 与 PHP 的结果集协议天然兼容。











