在 php 中 中, pdo :: exec ()是一个用于执行不返回结果集的 sql 语句的方法, 如삽입 、 삽입 、 、 、 、 等。尽管 等。尽管 pdo 提供了一个统一的接口来操作多种数据库 提供了一个统一的接口来操作多种数据库 提供了一个统一的接口来操作多种数据库 提供了一个统一的接口来操作多种数据库, 其行为存在一些微妙但关键的差异。本文将深入解析pdo :: exec ()在 mysql 、 postgresql 和 sqlite 三种数据库中的表现差异, 帮助开发者写出更具兼容性的跨库代码。 帮助开发者写出更具兼容性的跨库代码。
pdo :: exec (string $ station)返回一个整数值 返回一个整数值 返回一个整数值, 表示受影响的行数。若发生错误, 则返回false并可通过pdo :: errorinfo ()获取错误信息。
<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 s s, 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 1 이름原本就是 原本就是John , 那么返回的影响行数为0 , 因为没有真正的数据变更。
Postgresql l 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 | 可能统计未变更字段 | 类型宽松 类型宽松, 行为更像是“尝试执行” |
不依赖影响行数判断逻辑控制事务流。
짐
짐
虽然pdo :: exec ()提供了一种通用接口 提供了一种通用接口 提供了一种通用接口, 但背后的数据库差异决定了其行为并不总是完全一致。理解这些底层细节, 才能写出健壮、可移植的 php 程序。对于复杂操作, 考虑封装统一行为或使用数据库抽象层 考虑封装统一行为或使用数据库抽象层 考虑封装统一行为或使用数据库抽象层 考虑封装统一行为或使用数据库抽象层 (如 如 htrine) 是一个更好的选择。