在使用PHP 的mysqli擴展進行數據庫操作時,我們通常會通過mysqli::$affected_rows屬性來獲取SQL 語句執行後,受影響的行數。這個屬性返回了執行INSERT、UPDATE 或DELETE 操作後,實際改變的數據庫記錄行數。然而,有時即使插入數據成功,我們卻發現mysqli::$affected_rows返回的是0 行受影響,似乎插入並沒有生效。那麼,出現這種情況的原因是什麼呢?本文將詳細解析幾個常見原因,幫助你快速找出問題所在。
當使用INSERT IGNORE或REPLACE SQL 語句時,如果插入的記錄與現有記錄相同或違反了唯一性約束(比如主鍵或唯一索引),數據庫不會執行插入操作。這時,雖然SQL 語句被執行了,但實際上沒有任何行被插入到數據庫中,因此mysqli::$affected_rows返回的是0。需要注意的是,這種情況並不意味著插入失敗,而是因為沒有新記錄被添加。
<span><span><span class="hljs-variable">$sql</span></span><span> = </span><span><span class="hljs-string">"INSERT IGNORE INTO users (id, name) VALUES (1, 'Alice')"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">mysqli_query</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>, </span><span><span class="hljs-variable">$sql</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli_affected_rows</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>); </span><span><span class="hljs-comment">// 如果 ID 為 1 的用戶已存在,返回 0</span></span><span>
</span></span>
在使用AUTO_INCREMENT自增字段時,如果插入的記錄數據未能導致字段更新,可能會出現mysqli::$affected_rows返回0 的情況。例如,當你插入的數據已經包含了某個唯一約束的字段,而這個字段的值已經存在時,雖然插入操作成功,但是並未創建新的行, affected_rows返回的就會是0。
<span><span><span class="hljs-variable">$sql</span></span><span> = </span><span><span class="hljs-string">"INSERT INTO users (id, name) VALUES (1, 'Alice')"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">mysqli_query</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>, </span><span><span class="hljs-variable">$sql</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli_affected_rows</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>); </span><span><span class="hljs-comment">// 如果 ID 為 1 的記錄已存在,返回 0</span></span><span>
</span></span>
有時你可能會遇到INSERT語句被執行了,但返回的affected_rows為0 的情況,尤其是在批量插入的情況下。假如插入的數據已經存在且沒有違反唯一性約束,那麼這條INSERT語句雖然成功執行,但數據庫並未發生任何變化, affected_rows就會顯示為0。
<span><span><span class="hljs-variable">$sql</span></span><span> = </span><span><span class="hljs-string">"INSERT INTO users (id, name) VALUES (1, 'Alice')"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">mysqli_query</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>, </span><span><span class="hljs-variable">$sql</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli_affected_rows</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>); </span><span><span class="hljs-comment">// 如果 ID 1 的記錄已存在并且没有违反唯一约束,返回 0</span></span><span>
</span></span>
在使用事務時,只有當事務被提交(commit)後,插入操作才會生效。如果在事務執行過程中發生了錯誤或手動回滾了事務,那麼即使INSERT語句看似成功執行,實際上數據庫並沒有真正插入任何數據。因此, affected_rows也可能為0。
<span><span><span class="hljs-title function_ invoke__">mysqli_begin_transaction</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>);
</span><span><span class="hljs-variable">$sql</span></span><span> = </span><span><span class="hljs-string">"INSERT INTO users (name) VALUES ('Alice')"</span></span><span>;
</span><span><span class="hljs-title function_ invoke__">mysqli_query</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>, </span><span><span class="hljs-variable">$sql</span></span><span>);
</span><span><span class="hljs-comment">// 假設有某些條件觸發了回滾</span></span><span>
</span><span><span class="hljs-title function_ invoke__">mysqli_rollback</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli_affected_rows</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>); </span><span><span class="hljs-comment">// 返回 0,因為事务已回滚</span></span><span>
</span></span>
在使用mysqli執行SQL 時,有時我們沒有檢查數據庫連接是否成功,或者沒有捕捉到執行SQL 語句的錯誤。當mysqli_query()執行失敗時,返回的affected_rows很可能是0,因為沒有實際執行任何操作。因此,在進行數據庫操作時,務必檢查每次查詢執行的結果,確保沒有SQL 錯誤或數據庫連接問題。
<span><span><span class="hljs-variable">$sql</span></span><span> = </span><span><span class="hljs-string">"INSERT INTO users (name) VALUES ('Alice')"</span></span><span>;
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-title function_ invoke__">mysqli_query</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>, </span><span><span class="hljs-variable">$sql</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$result</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"SQL 執行失敗: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">mysqli_error</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>);
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">mysqli_affected_rows</span></span><span>(</span><span><span class="hljs-variable">$link</span></span><span>);
}
</span></span>
某些數據庫設置也可能導致affected_rows返回0。例如,MySQL 配置中可能有一些與sql_mode或transaction相關的設置,可能會影響查詢的行為。如果STRICT_TRANS_TABLES模式啟用並且插入的數據違反了某些限制,MySQL 可能不會執行插入操作,返回0。
在使用PHP 的mysqli擴展時,遇到mysqli::$affected_rows返回0 行受影響的情況並不罕見。通常情況下,這表明SQL 語句的執行並未改變數據庫中的數據。在排查這個問題時,可以從SQL 語句本身、數據庫設置、事務處理、數據完整性等多個方面進行檢查。了解這些常見的原因,可以幫助你快速定位問題並解決它。
相關標籤:
mysqli