使用mysqli,可以从预准备语句对象中检索最后插入的id,例如:
$pstm->execute();
$pstm->insert_id;
然而,对于PDO,这必须在数据库级别完成。 E.g:
$lastId = $dbh->lastInsertId();
我虽然PDO本来是要取代mysql / mysqli,为什么要做出这个设计决定呢?如果两个插入命令同时运行怎么办?因为插入的id没有作用于给定命令,所以它可能会检索错误的id?
由于
答案 0 :(得分:1)
MySQL LAST_INSERT_ID
函数在会话(数据库连接)级别维护。不是在个人预备声明中。该函数返回
由于最近执行的INSERT语句而成功为AUTO_INCREMENT列插入的第一个自动生成的值。
“我认为PDO意在取代mysql / mysqli”
我认为PDO应该是mysql_和mysqli_接口的替代。 PDO与其中任何一个都有很大的不同。首先,除MySQL之外的许多数据库都有PDO数据库驱动程序(例如DB2,Oracle,PostgreSQL,SQL Server等)。
相比之下,mysqli_接口专门支持MySQL(和MariaDB版本< 10.0,以及可能与MySQL兼容的其他一些版本。)
“为什么要做出这个设计决定?”
我认为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
函数实际上是会话(或链接的函数)的包装器/ passthru,正如mysqli所指的那样。)
如果是这种情况,那意味着在执行任何其他INSERT语句之前,需要在执行预准备语句INSERT之后立即调用insert_id
。
(我不确定其中的任何一个。可能可能 mysqli开发人员实现了代码,这些代码在成功执行预准备语句后立即自动运行SELECT LAST_INSERT_ID()
语句INSERT ,并在执行调用返回之前缓存。然后,当调用insert_id
函数时,它返回缓存的值。我真的不认为是这种情况。但它是可能的