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

PHP MySQLi multi_query 批次執行:INSERT/UPDATE/DELETE 混合執行實戰

     編輯:PHP 相關知識

PHP MySQLi multi_query 批次執行:INSERT/UPDATE/DELETE 混合執行實戰

MySQLi multi_query() 允許單次呼叫執行多條以分號分隔的 SQL 語句,大幅減少網路往返延遲。本文示範批次 INSERT 實作,並說明混合執行 DML、結果集處理差異與錯誤捕獲機制。

批次 INSERT 完整實作

<?php
// 1. 建立連線
$mysqli = new MySQLi("localhost", "root", "123456", "liuyan");
if ($mysqli->connect_error) die($mysqli->connect_error);
$mysqli->query("SET NAMES 'GBK'");

// 2. 組裝多條 SQL(以分號分隔)
$sqls = "INSERT INTO news(title, contents, datetime, hit) VALUES
('去哪兒網架構調整鋪墊上市','據接近去哪兒網的消息人士透露...','" . date('Y-m-d H:i:s') . "',30);";

$sqls .= "INSERT INTO news(title, contents, datetime, hit) VALUES
('告訴金主 視頻網站誰是NO.1','搜狐說,自己穩穩超過土豆...','" . date('Y-m-d H:i:s') . "',30);";

$sqls .= "INSERT INTO news(title, contents, datetime, hit) VALUES
('蘋果正滋生傲慢情緒','據國外媒體報道,沒有經歷重大挫折...','" . date('Y-m-d H:i:s') . "',30);";

// 3. 批次執行
$res = $mysqli->multi_query($sqls);

// 4. 結果判斷
if (!$res) {
    echo "批次執行失敗:" . $mysqli->error;
} else {
    echo "批次執行成功!";
}

// 5. 關閉連線
$mysqli->close();
?>

multi_query 核心特性與注意事項

1. 回傳值語義

  • true:第一條 SQL 執行成功(不代表後續都成功)
  • false:第一條 SQL 執行失敗

關鍵:必須配合 more_results() / next_result() 遍歷所有結果才能確知完整執行狀態。

2. 混合 DML 執行

可在同一 multi_query 中混合 INSERT/UPDATE/DELETE:

$mixedSql = "
    INSERT INTO log(event) VALUES('start');
    UPDATE accounts SET balance = balance - 100 WHERE id = 1;
    DELETE FROM temp_cache WHERE expired < NOW();
    INSERT INTO log(event) VALUES('end');
";
$mysqli->multi_query($mixedSql);

3. 完整結果遍歷模式(必須實作)

if ($mysqli->multi_query($sqls)) {
    do {
        // 處理每個結果集(SELECT 會有結果集,DML 則無)
        if ($result = $mysqli->store_result()) {
            // 有結果集(如 SELECT、SHOW、EXPLAIN)
            while ($row = $result->fetch_assoc()) {
                // 處理資料...
            }
            $result->free();
        } else {
            // 無結果集(INSERT/UPDATE/DELETE)
            // 可透過 $mysqli->affected_rows 取得影響列數
            echo "影響列數:" . $mysqli->affected_rows . "\n";
        }

        // 檢查是否還有下一個結果集
        if ($mysqli->more_results()) {
            echo "--- 處理下一個結果集 ---\n";
        }
    } while ($mysqli->next_result());
}

效能優化與生產建議

  1. 批次大小控制:單次 multi_query 建議不超過 1000 條或 1MB SQL 字串,避免超過 max_allowed_packet
  2. 事務配合:需原子性時包裹在 autocommit(false) / commit() / rollback() 中
  3. 錯誤定位:失敗時需遍歷結果集才能定位具體哪條 SQL 出錯
  4. 預處理替代:高頻批次寫入建議改用 prepare() + 迴圈 execute(),更安全且支援參數綁定
  5. LOAD DATA INFILE:超大量資料匯入優先考慮 MySQL 原生 LOAD DATA,效能優於 multi_query 數量級

常見陷阱提醒

  • 忘記呼叫 next_result() 導致後續查詢報錯 "Commands out of sync"
  • 混合 SELECT 時未正確釋放結果集造成記憶體洩漏
  • SQL 字串拼接時欠缺轉義導致注入風險(建議配合預處理或嚴格驗證)

善用 multi_query 可顯著降低高延遲網路環境下的批次寫入耗時,但務必建立完整的結果遍歷與錯誤處理機制。

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