首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP mysqli 多查詢 (multi_query) 批量執行與結果集遍歷實戰

     編輯:PHP 相關知識

mysqli::multi_query() 允許單次調用發送多條 SQL 語句(以分號分隔),配合 store_result()、next_result()、more_results() 遍歷所有結果集,適用於批量報表、Schema 遷移、減少網絡往返場景。

核心 API 流程

$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
$mysqli->set_charset('utf8mb4');

$sql = "SELECT * FROM news LIMIT 4; SELECT * FROM users; SELECT COUNT(*) AS c FROM logs;";

if ($mysqli->multi_query($sql)) {
    do {
        // 獲取當前結果集(SELECT/SHOW/EXPLAIN 等產生結果集的語句)
        if ($result = $mysqli->store_result()) {
            while ($row = $result->fetch_assoc()) {
                // 處理行數據
                print_r($row);
            }
            $result->free(); // 釋放內存
        }
        // 判斷是否還有後續結果集
        if ($mysqli->more_results()) {
            echo "--- Next Result Set ---\n";
        }
    } while ($mysqli->next_result()); // 移動到下一結果集,無則返回 false
}

$mysqli->close();

關鍵點詳解

  1. multi_query() 返回 bool,僅表示首條語句發送成功,**不代表所有語句執行成功**。
  2. store_result() 返回 mysqli_result 或 false(非結果集語句如 INSERT/UPDATE、或錯誤)。
  3. next_result() 同時執行「釋放前一結果集」與「準備下一結果集」,返回 bool 指示是否存在下一結果集。
  4. more_results() 僅檢查是否還有結果集,**不移動指針**。
  5. **錯誤處理**:循環中需檢查 $mysqli->errno,若非 0 則發生錯誤,後續結果集不可用。

進階:混合 DML 與 SELECT 的事務場景

$mysqli->autocommit(false);
$sql = "UPDATE accounts SET balance=balance-100 WHERE id=1;
        UPDATE accounts SET balance=balance+100 WHERE id=2;
        SELECT balance FROM accounts WHERE id IN (1,2);";

if ($mysqli->multi_query($sql)) {
    $hasError = false;
    do {
        if ($mysqli->errno) { $hasError = true; break; }
        if ($result = $mysqli->store_result()) {
            // 只有最後一條 SELECT 會進入這裡
            $row = $result->fetch_assoc();
            echo "Final balances: " . json_encode($row) . "\n";
            $result->free();
        }
    } while ($mysqli->next_result());

    if ($hasError) {
        $mysqli->rollback();
        echo "Transaction rolled back: " . $mysqli->error;
    } else {
        $mysqli->commit();
        echo "Transaction committed.";
    }
}

性能與適用場景

  • ✅ 減少客戶端-服務端往返(RTT),批量 DDL/DML 顯著加快。
  • ✅ 原子性需求可配合事務控制。
  • ❌ 單條超大結果集會阻塞內存,慎用 store_result(),改用 use_result() 非緩衝模式(但不可 next_result() 前讀完)。
  • ❌ 語句間有依賴關係時,錯誤定位困難(無法知曉具體第幾條失敗),建議拆分執行。

現代替代:PDO 不支援 multi_query

PDO 設計上**不支援多語句**(安全考量,防注入)。若用 PDO,請改用事務 + 循環執行單條預處理語句,或封裝 mysqli 專用類僅處理批量場景。

掌握 multi_query 完整流程,能在 Schema 部署、數據初始化、批量報表等場景大幅提升執行效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved