在使用PHP的mysqli擴展進行數據庫操作時, multi_query函數可以讓我們一次性執行多條SQL語句,這在批量處理數據時非常方便。但在執行多條語句後,如何正確獲取受影響的行數( affected_rows )就成為了一個常見的疑問。
本文將結合mysqli::$affected_rows屬性,講解在multi_query場景下,如何正確使用及需要注意的問題。
mysqli::$affected_rows是mysqli對象的一個屬性,表示最近一次執行的INSERT 、 UPDATE或DELETE語句所影響的行數。單條SQL語句執行時非常直觀:
$mysqli = new mysqli('gitbox.net', 'user', 'password', 'database');
$mysqli->query("UPDATE users SET status=1 WHERE last_login > NOW() - INTERVAL 30 DAY");
echo "受影響的行數: " . $mysqli->affected_rows;
執行完這條更新語句後, affected_rows即為受影響的行數。
multi_query允許一次性執行多條SQL語句:
$sql = "UPDATE users SET status=1 WHERE id=1;";
$sql .= "UPDATE users SET status=2 WHERE id=2;";
$mysqli->multi_query($sql);
但此時, affected_rows的值會是什麼呢?答案是: affected_rows只反映當前正在處理的結果集對應的受影響行數。由於multi_query需要循環處理每條語句的結果,必須一條一條去獲取。
示例代碼:
$mysqli = new mysqli('gitbox.net', 'user', 'password', 'database');
$sql = "UPDATE users SET status=1 WHERE id=1;";
$sql .= "UPDATE users SET status=2 WHERE id=2;";
$sql .= "DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY;";
if ($mysqli->multi_query($sql)) {
do {
// 獲取當前結果的受影響行數
echo "受影響行數: " . $mysqli->affected_rows . "\n";
// 準備處理下一個結果
} while ($mysqli->more_results() && $mysqli->next_result());
} else {
echo "執行失敗: " . $mysqli->error;
}
這裡我們用do...while循環逐條處理語句,每執行完一條就讀取當前的affected_rows ,才能準確獲取每條語句的影響行數。
multi_query必須配合next_result()逐條遍歷結果<br> 不調用next_result( ) ,只能拿到第一條語句的affected_row s ,後面的語句會被忽略
某些語句可能沒有影響行數<br> 例如SELECT語句, affected_rows返回- 1只對修改數據的語句有效。
出錯時affected_rows可能為-1
如果SQL語句執行失敗, affected_rows會返回-1 。此時需通過$mysqli->error獲取錯誤信息。
事務處理時要注意一致性<br> 如果多個語句在事務中執行,單條語句的affected_rows不能保證事務整體的最終狀態,需要根據事務提交與回滾來控制
在multi_query執行多條SQL時,必須用循環配合next_result()才能遍歷所有結果。
每條語句執行後, affected_rows才是當前語句的受影響行數。
注意檢測錯誤狀態和特殊語句對affected_rows的返回值。
對事務操作時,受影響行數只是輔助判斷,最終狀態以事務提交結果為準。
掌握了以上要點,你就能正確高效地使用mysqli::$affected_rows配合multi_query進行多條SQL的執行與結果處理。