mysqli_affected_rows有什么用_获取影响行数的方法【操作】

7次阅读

mysqli_affected_rows 返回上一次insert、update、delete或replace实际影响的行数;对select等只读语句固定返回-1,非错误;update值未变时返回0;事务中不回滚其值。

mysqli_affected_rows有什么用_获取影响行数的方法【操作】

mysqli_affected_rows 返回什么值?

mysqli_affected_rows 不是“执行成功就返回 1”,它只反映上一次 INSERTUPDATEDELETEREPLACE 实际改动的行数。对 SELECTSHOWDESCRIBE 这类只读语句,它固定返回 -1 —— 这不是报错,是设计如此。

常见误判:看到 -1 就以为 SQL 执行失败,其实可能只是你刚查完数据又顺手调了 mysqli_affected_rows,它没东西可报。

  • INSERT INTO … VALUES (…) → 成功插入 1 行,返回 1;插入多行,返回实际行数
  • UPDATE … WHERE id = 123 → 即使条件匹配,但新旧值完全一样(比如 SET status=’done’ 但原来就是 ‘done’),MySQL 默认不计为“影响”,返回 0(除非开启 sql_mode=STRICT_TRANS_TABLES 并配合其他设置)
  • DELETE FROM t WHERE 1=0 → 匹配 0 行,返回 0;不是报错,也不是 NULL

为什么 mysqli_affected_rows 有时返回 -1?

根本原因:它只对“修改类”语句有效。一旦你混用查询和更新,或在 mysqli_query 后没立刻调用它,就容易踩坑。

典型场景:

  • mysqli_query($conn, "SELECT * FROM users"),再 mysqli_affected_rows($conn) → 必然 -1
  • mysqli_multi_query 执行多个语句,但没用 mysqli_next_result 切换结果集,直接调 mysqli_affected_rows → 返回的是第一个语句的影响数,后续的全丢
  • 连接被复用,前一个请求是 SELECT,当前请求是 UPDATE,但忘了检查上一步是否真执行了写操作 → 值来自上一个 SELECT,还是 -1

验证方法:在每次 INSERT/UPDATE/DELETE 后**立即**调用 mysqli_affected_rows,且确保前面没有其他非修改语句干扰。

与 mysqli_num_rows 的区别在哪?

mysqli_num_rows 数的是 SELECT 结果集有多少行,mysqli_affected_rows 数的是写操作实际变更了几行 —— 它们压根不在一个维度,不能互相替代,也不能混着判断逻辑。

错误用法示例:

if (mysqli_affected_rows($conn) > 0) {     // 以为这是“查到了数据”,其实这是“改了数据” }

正确对应关系:

  • 想确认 INSERT 是否成功插入 → 看 mysqli_affected_rows 是否 ≥ 1
  • 想确认 UPDATE 是否真的改了内容(而非白跑一趟)→ 看 mysqli_affected_rows 是否 > 0(注意:0 表示匹配但未变更)
  • 想确认 SELECT 返回了几条记录 → 必须用 mysqli_num_rows,且要传入 mysqli_query 返回的结果资源,不是连接资源

事务中怎么安全用 mysqli_affected_rows?

START TRANSACTION 后,每个语句仍会独立影响 mysqli_affected_rows 的返回值,但它**不感知事务最终是否提交**。也就是说,即使你最后 ROLLBACK,之前各步的 mysqli_affected_rows 值也不会回滚或清零。

所以别靠它判断事务是否生效。真正该做的:

  • 每条写语句后立刻捕获 mysqli_affected_rows,存到变量里(如 $inserted = mysqli_affected_rows($conn);)
  • 等整个事务 COMMIT 成功后再用这些变量做业务判断
  • 如果 ROLLBACK,那些变量的值依然存在,但已失效 —— 你需要重置逻辑,而不是重读 mysqli_affected_rows

最容易被忽略的一点:pdorowCount() 在预处理后行为更一致,而原生 mysqli 的这个函数对无符号整数、大数值、甚至某些 MySQL 版本的 INSERT ... ON DUPLICATE KEY UPDATE 返回值都有微妙差异,生产环境建议加类型断言或范围校验。

text=ZqhQzanResources