当前位置: 首页> 最新文章列表> 【mysqli::$affected_rows】插入成功却返回0行受影响?可能原因一次说清楚

【mysqli::$affected_rows】插入成功却返回0行受影响?可能原因一次说清楚

gitbox 2025-08-16

在使用 PHP 的 mysqli 扩展进行数据库操作时,我们通常会通过 mysqli::$affected_rows 属性来获取 SQL 语句执行后,受影响的行数。这个属性返回了执行 INSERT、UPDATE 或 DELETE 操作后,实际改变的数据库记录行数。然而,有时即使插入数据成功,我们却发现 mysqli::$affected_rows 返回的是 0 行受影响,似乎插入并没有生效。那么,出现这种情况的原因是什么呢?本文将详细解析几个常见原因,帮助你快速找出问题所在。

1. 使用 INSERT IGNOREREPLACE 语句

当使用 INSERT IGNOREREPLACE 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>

2. 自动生成的自增 ID

在使用 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>

3. INSERT 执行后没有变化的场景

有时你可能会遇到 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>

4. 事务未提交或被回滚

在使用事务时,只有当事务被提交(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>

5. 未检查数据库连接或 SQL 执行是否成功

在使用 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>

6. 数据库设置或其他配置问题

某些数据库设置也可能导致 affected_rows 返回 0。例如,MySQL 配置中可能有一些与 sql_modetransaction 相关的设置,可能会影响查询的行为。如果 STRICT_TRANS_TABLES 模式启用并且插入的数据违反了某些限制,MySQL 可能不会执行插入操作,返回 0。

结论

在使用 PHP 的 mysqli 扩展时,遇到 mysqli::$affected_rows 返回 0 行受影响的情况并不罕见。通常情况下,这表明 SQL 语句的执行并未改变数据库中的数据。在排查这个问题时,可以从 SQL 语句本身、数据库设置、事务处理、数据完整性等多个方面进行检查。了解这些常见的原因,可以帮助你快速定位问题并解决它。