在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 。