當前位置: 首頁> 最新文章列表> 執行UPDATE 操作時,忘記檢查是否有匹配行,會對mysqli::$affected_rows 的值產生什麼影響?

執行UPDATE 操作時,忘記檢查是否有匹配行,會對mysqli::$affected_rows 的值產生什麼影響?

M66 2025-06-29

在使用PHP 的MySQLi 擴展進行數據庫操作時, UPDATE語句是最常用的SQL 操作之一。然而,許多開發者在執行UPDATE操作時,常常忽略了一個關鍵細節:在執行更新之前,並未驗證是否確實有匹配的記錄。這種忽略,會直接影響到mysqli::$affected_rows屬性的值,進而可能導致程序邏輯錯誤或異常行為。

1. mysqli::$affected_rows的定義與作用

在MySQLi 中,每次執行數據修改操作(如INSERTUPDATEDELETE )後, $mysqli->affected_rows會返回受影響的行數。這個值在很多應用場景中被用於判斷操作是否成功,或用於記錄操作日誌等。

例如:

<code> $mysqli = new mysqli("localhost", "user", "pass", "database");

$mysqli->query("UPDATE users SET status = 'active' WHERE last_login < NOW() - INTERVAL 30 DAY");

echo $mysqli->affected_rows;
</code>

該代碼會輸出受影響的行數,即成功更新狀態的用戶數量。

2. 沒有匹配行時的行為

當執行的UPDATE語句沒有匹配任何記錄時, $mysqli->affected_rows會返回0 。這是因為沒有任何記錄被修改,無論語法是否正確、SQL 是否成功執行,受影響行數仍為0。

注意:即使SQL 語句語法完全正確,如果WHERE 條件沒有命中任何數據, affected_rows依然為0。這並不代表SQL 執行失敗。

例如:

<code> $mysqli = new mysqli("localhost", "user", "pass", "database");

$mysqli->query("UPDATE users SET status = 'active' WHERE id = 999999");

echo $mysqli->affected_rows;
</code>

假設id = 999999的用戶不存在,則輸出將是0 ,說明沒有記錄被更新。

3. 數據沒有變更時的情況

此外,還有一種情況容易被誤解:即使有記錄被匹配,如果更新後的值與原值相同,也不會計入受影響的行數。

例如:

<code> $mysqli = new mysqli("localhost", "user", "pass", "database");

$mysqli->query("UPDATE users SET status = 'active' WHERE status = 'active'");

echo $mysqli->affected_rows;
</code>

這段代碼中,雖然可能匹配了許多行,但由於status字段原本就已經是'active' ,所以沒有實際的數據修改動作發生,MySQL 會認為沒有任何行被“影響”,返回0

4. 正確處理affected_rows的方式

如果你依賴affected_rows來判斷操作是否成功,務必考慮以下兩點:

  • SQL 執行是否成功(可通過$mysqli->errno$mysqli->error判斷)

  • affected_rows是否為正值,表示確實有數據被修改

完整示例:

<code> $mysqli = new mysqli("localhost", "user", "pass", "database");

$result = $mysqli->query("UPDATE users SET status = 'inactive' WHERE last_login < NOW() - INTERVAL 1 YEAR");

if ($result === false) {
die("SQL 錯誤:" . $mysqli->error);
} elseif ($mysqli->affected_rows > 0) {
echo "成功更新了{$mysqli->affected_rows} 條記錄。";
} else {
echo "沒有記錄被更新。";
}
</code>

5. 實際案例提醒

在構建管理系統或接口時,開發者可能希望通過返回affected_rows來驗證客戶端傳入的條件是否命中任何數據。如果沒有事先提醒這一機制,可能會導致客戶端錯誤地認為更新失敗或服務端出錯。

例如,一個接口:

<code> POST /api/update-status.php?user_id=123 HTTP/1.1 Host: m66.net </code>

如果用戶ID 不存在,而接口代碼僅根據affected_rows判斷操作是否成功,客戶端可能誤認為系統出錯。應通過更明確的響應信息告知是“無匹配記錄”,而非“操作失敗”。

總結

在PHP 的MySQLi 操作中, $mysqli->affected_rows是判斷數據是否實際發生變動的重要手段。但需要注意的是:

  • 沒有匹配記錄時,值為0

  • 匹配了記錄但更新前後數據相同,也返回0

  • SQL 執行錯誤不會反映在affected_rows ,需額外判斷

開發者在使用這一屬性時,應全面理解其行為,避免邏輯漏洞或誤判更新結果。