当前位置: 首页> 最新文章列表> 如何用 next_result() 优雅处理 SQL Server 的多个结果集

如何用 next_result() 优雅处理 SQL Server 的多个结果集

gitbox 2025-05-06

在 PHP 中操作 SQL Server(尤其是使用 sqlsrv 扩展)时,我们常常会遇到存储过程或批量查询语句返回的情况。要正确处理这些结果集,仅使用 sqlsrv_fetch_array() 是不够的,我们还需要搭配使用 sqlsrv_next_result() 函数。本文将介绍如何优雅而安全地使用 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