2

PDO::lastInsertId()最後に挿入された行の ID (主キー) を返さず、代わりに外部キー フィールドである別のフィールドを返すメソッドに問題があります。

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 テーブル構造:

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

MySQL に挿入された行:

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

PHP 出力:

last inserted id: 19

1notを返す必要があり19ます。私のコードに何か問題があるかどうかはわかりません..または、これは通常の動作です:?

戻り値 (PHP ドキュメント):

  • name パラメーターにシーケンス名が指定されていない場合は 、データベースに挿入された最後の行の行をPDO::lastInsertId()表す文字列を返します。ID

  • name パラメーターにシーケンス名が指定された場合、PDO::lastInsertId()指定されたシーケンス オブジェクトから取得された最後の値を表す文字列を返します。

  • PDOドライバーがこの機能をサポートしていない場合はPDO::lastInsertId()IM001 SQLSTATE.

4

2 に答える 2

1

クエリを実行し"SELECT LAST_INSERT_ID()"ます。
返されたIDが2ではなく19(またはすべての試行後に必要な主キー)である場合は、MySQLに問題があり、PDOとは関係ありません。別のケース(そしておそらく別の質問)として調査し、コンソールで実行できる完全なSQLプルーフコードを提供し、テーブルの作成、挿入の実行、およびLAST_INSERT_ID()の選択を行う必要があります。

この関数が正しい値を返すが、PDOがまだ間違っている場合は、おそらくbugs.php.netでバグレポートを作成する必要があります。ここでも、完全に再現可能なコードと、正確なバージョン番号が指定されたすべてのソフトウェア名を使用します。

明確にするための1つのことだけです$sql。質問の変数に、INSERT ON DUPLICATEなどではなく、適切なINSERTステートメントが含まれていることを確認してください。または、このINSERTにトリガーが設定されていますか?

于 2013-01-14T06:57:51.180 に答える
-1

最近PDO::lastInsertId()を調べましたが、マニュアルの説明が十分に説得力がない(または実際に理解できる)ため、代わりに次のようなものを使用することにしました。

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

それは私のために働くようです。

私はPDOまたはMySQLの専門家ではないため、これは正しくない可能性がありますが、上記のアプローチにより、このスレッドの間に別の行が(別のユーザー/スレッドによって)データベースに挿入されるという問題を回避できると思いました。 execute()およびlastInsertID()呼び出し。

lastInsertID()を維持したい場合は、セットアップで、返されるIDが自動インクリメントフィールドである必要があるかどうかを調査しましたか?これはそうあるべきであるが、絶望的な曖昧さ(IMHO)であるという手動の種類のヒント。

それがお役に立てば幸いです。

乾杯、イアン。

于 2013-01-14T06:11:45.440 に答える