在php中, pDO :: exec()是一個用於執行不返回結果集的sql語句的方法,如插入,defude delete delete等。儘管pdo提供了一個統一的接口來操作多種數據庫,但在不同的數據庫系統之間,其行為存在一些微妙但關鍵的差異。本文將深入解析pdO :: exec()在mysql postgreSql postgreSql postgreSql postgresql sqlite sqlite三種數據庫中的表現差異
pdo :: exec(字符串$語句)返回一個整數值
<span><span><span class="hljs-variable">$db</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-string">'mysql:host=localhost;dbname=test'</span></span><span>, </span><span><span class="hljs-string">'user'</span></span><span>, </span><span><span class="hljs-string">'pass'</span></span><span>);
</span><span><span class="hljs-variable">$count</span></span><span> = </span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">"UPDATE users SET status = 'active' WHERE last_login > NOW() - INTERVAL 30 DAY"</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"影响的行数: <span class="hljs-subst">$count</span></span></span><span>";
</span></span>
在mysql中, pdo :: exec()的行為相對直觀。只要sql執行成功,它就會返回受影響的行數。這裡的“受影響”是指值實際發生變化的行。
例如:
<span><span><span class="hljs-variable">$db</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-string">"mysql:host=gitbox.net;dbname=demo"</span></span><span>, </span><span><span class="hljs-string">"user"</span></span><span>, </span><span><span class="hljs-string">"pass"</span></span><span>);
</span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">"UPDATE users SET name = 'John' WHERE id = 1"</span></span><span>);
</span></span>
如果用戶ID= 1的名John ,那麼返回的影響行數為0 ,因為沒有真正的數據變更。 ,因為沒有真正的數據變更。
postgresql pdo :: exec()時返回的也是影響行數,但有一個小區別:默認開啟事務機制。如果你沒有顯式提交事務,更新可能並未真正寫入數據庫。
此外,postgresql 會將視圖、觸發器等邏輯更新的結果計入影響行數。
<span><span><span class="hljs-variable">$db</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-string">"pgsql:host=gitbox.net;dbname=demo"</span></span><span>, </span><span><span class="hljs-string">"user"</span></span><span>, </span><span><span class="hljs-string">"pass"</span></span><span>);
</span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">"UPDATE products SET price = price * 1.1 WHERE category = 'Books'"</span></span><span>);
</span></span>
((),返回的行數將反映所有級聯影響的記錄數。
sqlite與其他兩者最大的不同在於其輕量級實現。雖然也返回受影響的行數,但有些操作表現得不同::
沒有類型強校驗:可能導致看起來“無變化”的字段也算作已更新。
空事務優化少:即使值相同,某些情況下也返回,某些情況下也返回1行被影響。
<span><span><span class="hljs-variable">$db</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-title function_ invoke__">PDO</span></span><span>(</span><span><span class="hljs-string">"sqlite:/path/to/gitbox.net-demo.db"</span></span><span>);
</span><span><span class="hljs-variable">$count</span></span><span> = </span><span><span class="hljs-variable">$db</span></span><span>-></span><span><span class="hljs-title function_ invoke__">exec</span></span><span>(</span><span><span class="hljs-string">"UPDATE users SET email = '[email protected]' WHERE id = 5"</span></span><span>);
</span></span>
即便用戶的電子郵件沒有變化,sqlite在某些版本中仍可能返回1 ,這在邏輯判斷中需要格外注意。
資料庫 | 相同行數計算規則 | 特殊注意事項 |
---|---|---|
mysql | 值實際變更時才計入 | 忽略未變更字段,不計入影響行數 |
Postgresql | 計入觸發器、級聯等邏輯行數 | 默認事務機制,需手動提交 |
sqlite | 可能統計未變更字段 | 類型寬鬆,行為更像是“嘗試執行” |
不依賴影響行數判斷邏輯控制事務流。
在多數據庫環境中,考慮使用,選擇查詢先對比變更內容,避免誤判。 ,避免誤判。
明確事務開始與提交,特別是在postgresql中。
PDO :: exec()提供了一種通用接口,但背後的數據庫差異決定了其行為並不總是完全一致。理解這些底層細節