MySQLLAST_INSERT_ID 函数在会话(数据库连接)级别维护。不是在个人准备好的声明中。该函数返回
作为最近执行的 INSERT 语句的结果,为 AUTO_INCREMENT 列成功插入的第一个自动生成的值。
“我认为 PDO 是为了取代 mysql/mysqli”
我认为 PDO 旨在成为 mysql_ 和 mysqli_ 接口的替代。 PDO 与其中任何一个都有很大不同。一方面,除了 MySQL 以外的许多数据库(如 DB2、Oracle、PostgreSQL、SQL Server 等)都有 PDO 数据库驱动程序。
相比之下,mysqli_ 接口专门支持 MySQL(和 MariaDB 版本
“为什么做出这个设计决定?”
我认为 PDO 设计更接近 MySQL 数据库本身中 LAST_INSERT_ID 函数的模式。 PDO 和 mysqli 都提供“包装器”函数作为从 SELECT LAST_INSERT_ID() 语句执行和检索结果集的便捷方式。
我相信 PDO 的开发人员希望它成为多个数据库的轻量级且一致的接口。为 mysql/mysqli 创建一个替代品并不是主要的设计目标。
“如果两个插入命令同时运行会怎样?”
不可能在单个 MySQL 数据库会话上“同时”运行两个 INSERT 语句。它们会连续运行。
在 MySQL 中,要从第一个 INSERT 语句中检索 AUTO_INCREMENT 值,第一个语句需要在执行第二个 INSERT 语句之前跟一个 SELECT LAST_INSERT_ID()。
“因为插入的 id 没有作用于给定的命令,它可能会检索到错误的 id 吗?”
这是 MySQL LAST_INSERT_ID() 函数的设计。它没有“范围”到特定的语句。该函数返回的值会为会话保留。
mysqli 接口在会话级别为 LAST_INSERT_ID() 函数提供了一个包装器。
参考:http://php.net/manual/en/mysqli.insert-id.php
就为准备好的语句提供方法/函数而言,我从未使用过。
我怀疑在准备好的语句中,insert_id 函数实际上是会话(或链接,如 mysqli 所指的那样)函数的包装器/通路。
如果是这种情况,这意味着需要在执行准备好的语句 INSERT 之后立即调用 insert_id,然后再执行任何其他 INSERT 语句。
(我不太确定。可能mysqli 开发人员实现了在成功执行准备好的语句 INSERT 后立即自动运行 SELECT LAST_INSERT_ID() 语句的代码,并且在执行调用返回之前缓存它。然后,当调用insert_id 函数时,它会返回缓存的值。我不认为是这样。但它是可能。如果那样在这种情况下,我仍然不会让我的代码依赖于这种行为。我希望在 INSERT 之后立即获取 LAST_INSERT_ID(),然后再在 MySQL 会话上运行任何其他语句。