在 PHP 中操作 SQL Server(尤其是使用 sqlsrv 扩展)时,我们常常会遇到存储过程或批量查询语句返回的情况。要正确处理这些结果集,仅使用 sqlsrv_fetch_array() 是不够的,我们还需要搭配使用 sqlsrv_next_result() 函数。本文将介绍如何优雅而安全地使用 next_result() 来遍历所有返回的结果集。
在 SQL Server 中,一个查询可以返回多个结果集,例如:
SELECT * FROM users;
SELECT * FROM orders;
执行这样的查询时,PHP 必须使用 sqlsrv_next_result() 来遍历这两个结果集。
我们先来看一个简单的例子:
<?php
$serverName = "localhost";
$connectionOptions = array(
"Database" => "MyDatabase",
"Uid" => "myuser",
"PWD" => "mypassword"
);
// 建立连接
$conn = sqlsrv_connect($serverName, $connectionOptions);
if ($conn === false) {
die(print_r(sqlsrv_errors(), true));
}
// 执行包含多个结果集的 SQL 查询
$sql = "SELECT * FROM users; SELECT * FROM orders;";
$stmt = sqlsrv_query($conn, $sql);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
$resultIndex = 1;
do {
echo "处理第 {$resultIndex} 个结果集:\n";
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
print_r($row);
}
$resultIndex++;
} while (sqlsrv_next_result($stmt));
// 释放资源
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>
在一些企业应用中,常用存储过程来实现分页,这类存储过程往往返回两个结果集:一个是数据列表,另一个是总记录数:
-- 假设的分页存储过程
CREATE PROCEDURE GetPagedUsers
AS
BEGIN
SELECT * FROM users ORDER BY id OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;
SELECT COUNT(*) AS TotalCount FROM users;
END
我们在 PHP 中处理时,可以这样:
$sql = "{CALL GetPagedUsers()}";
$stmt = sqlsrv_query($conn, $sql);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
// 第一个结果集:数据列表
$users = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$users[] = $row;
}
// 移动到下一个结果集
if (sqlsrv_next_result($stmt)) {
// 第二个结果集:总记录数
if ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$totalCount = $row['TotalCount'];
}
}
print_r([
'users' => $users,
'totalCount' => $totalCount,
]);
资源释放:务必在最后调用 sqlsrv_free_stmt() 来释放语句资源。
结果集顺序要清晰:多个结果集的顺序完全由 SQL 的顺序决定。
防止空结果集:调用 sqlsrv_next_result() 后要检查是否返回了新的数据。
通过合理使用 sqlsrv_next_result(),我们可以优雅地处理 SQL Server 返回的多个结果集,在分页、统计、合并查询等业务场景中发挥巨大作用。记得,在生产环境中调用这类接口时,务必做好错误处理和资源释放,确保系统稳定运行。
如需进一步了解 SQL Server 与 PHP 的结合方式,可以访问官方文档或我们的教程平台:https://gitbox.net/php-sqlserver。