简体   繁体   English

使用PDO获取最后插入的行ID(不合适的结果)

[英]getting last inserted row id with PDO (not suitable result)

I have a problem with PDO::lastInsertId() method which doesn't return the id (primary key) of last inserted row, instead it returns another field which is a foreign key field. 我对PDO::lastInsertId()方法有问题,该方法不返回最后插入的行的ID(主键),而是返回另一个字段,即外键字段。

PHP code: PHP代码:

$pdo = new PDO(...);
$stmt = $pdo->prepare($sql);
$stmt->bindParam(...);
$stmt->bindParam(...);
$stmt->execute();
$id = $pdo->lastInsertId();
// or
$id = $pdo->lastInsertId('services_id_seq'); // I think 'services_id_seq' is not necessary in MySQL
// both of them don't return the primary key of last inserted row

echo 'last inserted id: ' . $id;

MySQL Table structure: MySQL表结构:

...
id          int unsigned not null primary key auto_increment
customer_id int unsigned not null
user_id     int unsigned not null
....

inserted row in MySQL: 在MySQL中插入行:

id    customer_id    user_id    ...
1     19             31         ...

PHP output: PHP输出:

last inserted id: 19

It should return 1 not 19 . 它应该返回1而不是19 I don't know is anything wrong with my code or not.. or maybe this is the normal behavior :? 我不知道我的代码有什么问题..也许这是正常现象:?

Return Value (PHP documentation): 返回值(PHP文档):

  • If a sequence name was not specified for the name parameter, PDO::lastInsertId() returns a string representing the row ID of the last row that was inserted into the database. 如果没有为name参数指定序列名称,则PDO::lastInsertId()返回一个字符串,该字符串表示插入数据库的最后一行的行ID

  • If a sequence name was specified for the name parameter, PDO::lastInsertId() returns a string representing the last value retrieved from the specified sequence object. 如果为name参数指定了序列名称,则PDO::lastInsertId()返回一个字符串,该字符串表示从指定序列对象中检索到的最后一个值。

  • If the PDO driver does not support this capability, PDO::lastInsertId() triggers an IM001 SQLSTATE . 如果PDO驱动程序不支持此功能,则PDO::lastInsertId()会触发IM001 SQLSTATE

Run "SELECT LAST_INSERT_ID()" query. 运行"SELECT LAST_INSERT_ID()"查询。
If returned ID is still 19, not 2 (or whatever primary key should be after all tries), there is a problem with MySQL, irrelevant to PDO. 如果返回的ID仍为19,而不是2(或在尝试后应使用任何主键),则MySQL存在问题,与PDO无关。 You have to investigate it as a separate case (and, probably, separate question), supplying full SQL proof-code, able to run in console, involving creating a table, running insert and selecting LAST_INSERT_ID() 您必须将其作为一个单独的案例进行研究(并且可能要单独回答一个问题),提供完整的SQL证明代码,能够在控制台中运行,包括创建表,运行插入并选择LAST_INSERT_ID()

If this function returns the right value but PDO still wrong one - you have to probably bugreport it on bugs.php.net, again with full reproduceable code and all software names with exact version numbers provided. 如果此函数返回正确的值,但PDO仍然是错误的-您可能必须在bugs.php.net上对其进行bug报告,再次使用完整的可复制代码和所有提供了确切版本号的软件名称。

Only one thing to make it clear: are you certainly sure that $sql variable in your question contains proper INSERT statement, not something like INSERT ON DUPLICATE or such? 只有一件事要弄清楚:您是否确定问题中的$sql变量包含正确的INSERT语句,而不是诸如INSERT ON DUPLICATE之类的东西? Or are there any triggers set on this INSERT? 还是在此INSERT上设置了任何触发器?

I looked at PDO::lastInsertId() recently but found the description in the manual insufficiently convincing (or indeed comprehensible) and so opted for using something like this instead: 我最近查看了PDO :: lastInsertId(),但发现手册中的描述不足以令人信服(或确实可以理解),因此选择改用如下形式:

...
$stmt->execute();
$row = $stmt->fetch();
...

which seems to work for me. 这似乎对我有用。

I'm no PDO or MySQL expert, so this may not be quite right, but I also thought that the above approach would circumvent the possible problem of another row being inserted in the database (by a different user/thread) in between this thread's execute() and lastInsertID() calls. 我不是PDO或MySQL专家,所以这可能不太正确,但是我还认为上述方法可以避免在该线程的两个线程之间(通过不同的用户/线程)将另一行插入数据库的可能问题。 execute()和lastInsertID()调用。

If you're keen to keep lastInsertID() have you investigated whether, in your setup, the ID returned has to be an auto-increment field? 如果您想保留lastInsertID(),是否已调查在您的设置中返回的ID是否必须为自动递增字段? The manual sort of hints that this should be so but is hopeless vague (IMHO). 手动提示应该是这样,但是是没有希望的含糊(恕我直言)。

Hope that's of some help. 希望对您有所帮助。

Cheers, Ian. 干杯,伊恩。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM