php中、 pdo :: exec()是一个用于执行不返回结果集的sql
pdo :: exec(String $ statement)返回一个整数值、表示受影响的行数。若发生错误、则返回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中、 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的name原本就是ジョン、那么返回的影响行数为0 、因为没有真正的数据变更。
postgreSql
此外、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 | 可能统计未变更字段 | 类型宽松、行为更像是「尝试执行」 |
不依赖影响行数判断逻辑控制事务流。
在多数据库环境中、考虑使用select查询先对比变更内容、避免误判。
明确事务开始与提交、特别是在postgresql中。
pdo :: exec()提供了一种通用接口、但背后的数据库差异决定了其行为并不总是完全一致。理解这些底层细节、才能写出健壮、可移植的 php程序。对于复杂操作、考虑封装统一行为或使用数据库抽象层(如教義)是一个更好的选择。