ホームページ > バックエンド開発 > PHPチュートリアル > 【PDO拡張】lastInsertId関数が0を返す理由

【PDO拡張】lastInsertId関数が0を返す理由

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-06-20 12:39:36
オリジナル
988 人が閲覧しました

問題

PHP の PDO 拡張機能を使用してデータを挿入する場合、最後に挿入されたレコードの ID を戻り情報として取得する必要がある場合があります。どうすればこの要件を達成できるでしょうか?

lastInsertId 関数

PDO の lastInsertId 関数を使用します。

しかし、最近使用中に、lastInsertId 関数が 0 を返す場合があることがわかりました。なぜこのようなことが起こっているのでしょうか?

まず、PHP マニュアルの lastInsertId 関数の説明を見てみましょう。

最後に挿入された行の ID またはシーケンス値を返します。

次の例を見てみましょう。

テスト例

自動インクリメント制約を使用した主キーは ID フィールドです。

<?php    $dsn = 'mysql:dbname=test;host=127.0.0.1';    $user = 'root';    $password = 'root';    try{            $dbh = new PDO($dsn, $user, $password);    }catch(PDOException $e){            echo "Connection failed: " . $e->getMessage();    }    for( $i = 0; $i < 10; $i++){            $sql = 'INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)';            $data = array(                    ':id' => '',                    ':name' => "user_$i"            );            $sth = $dbh->prepare($sql);            $sth->execute($data);    }    $sql = 'INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)';    $new_data = array(            ':id' => '',            ':name' => 'user_new'    );    $sth = $dbh->prepare($sql);    $sth->execute($new_data);    $last_id = $dbh->lastInsertId();    echo 'last id: ' . $last_id;
ログイン後にコピー

結果

last id: 11

主キーは ID フィールドであり、auto は使用されません-インクリメント制約。

<?php    $dsn = 'mysql:dbname=test;host=127.0.0.1';    $user = 'root';    $password = 'root';    try{            $dbh = new PDO($dsn, $user, $password);    }catch(PDOException $e){            echo "Connection failed: " . $e->getMessage();    }    for( $i = 0; $i < 10; $i++){            $sql = 'INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)';            $data = array(                    ':id' => $i,                    ':name' => "user_$i"            );            $sth = $dbh->prepare($sql);            $sth->execute($data);    }    $sql = 'INSERT INTO `tbl_test` (id, name) VALUE (:id, :name)';    $new_data = array(            ':id' => '',            ':name' => 'user_new'    );    $sth = $dbh->prepare($sql);    $sth->execute($new_data);    $last_id = $dbh->lastInsertId();    echo 'last id: ' . $last_id;
ログイン後にコピー

結果

last id: 0

主キーは ID フィールドではなく、主キーkey は自動インクリメント制約を使用します。

<?php    $dsn = 'mysql:dbname=test;host=127.0.0.1';    $user = 'root';    $password = 'root';    try{            $dbh = new PDO($dsn, $user, $password);    }catch(PDOException $e){            echo "Connection failed: " . $e->getMessage();    }    for( $i = 0; $i < 10; $i++){            $sql = 'INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)';            $data = array(                    ':tbl_id' => $i,                    ':name' => "user_$i"            );            $sth = $dbh->prepare($sql);            $sth->execute($data);    }    $sql = 'INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)';    $new_data = array(            ':tbl_id' => '',            ':name' => 'user_new'    );    $sth = $dbh->prepare($sql);    $sth->execute($new_data);    $last_id = $dbh->lastInsertId();    echo 'last id: ' . $last_id;
ログイン後にコピー

結果

last id: 11

主キーは ID フィールドではないため、使用されません自動インクリメント制約。

<?php    $dsn = 'mysql:dbname=test;host=127.0.0.1';    $user = 'root';    $password = 'root';    try{            $dbh = new PDO($dsn, $user, $password);    }catch(PDOException $e){            echo "Connection failed: " . $e->getMessage();    }    for( $i = 0; $i < 10; $i++){            $sql = 'INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)';            $data = array(                    ':tbl_id' => uniqid(),                    ':name' => "user_$i"            );            $sth = $dbh->prepare($sql);            $sth->execute($data);    }    $sql = 'INSERT INTO `tbl_test` (tbl_id, name) VALUE (:tbl_id, :name)';    $new_data = array(            ':tbl_id' => uniqid(),            ':name' => 'user_new'    );    $sth = $dbh->prepare($sql);    $sth->execute($new_data);    $last_id = $dbh->lastInsertId();    echo 'last id: ' . $last_id;
ログイン後にコピー

結果

last id: 0

PHP ソースコードを表示

を参照してください。一部の例では 0 が返され、一部の例では最新の ID が返されます。それでは、どのような状況で lastInsertId は 0 を返すのでしょうか?インターネットで多くの情報を検索しましたが、必要な答えが見つかりませんでした。PHP ソース コードを開いたところ、関数 last_insert_id の実装ソース コードが次のとおりであることがわかりました。 > ご覧のとおり、関数によって返される ID 値は、mysql API の mysql_insert_id 関数を呼び出して返される値です。

mysql マニュアルを表示

mysql マニュアルを開いて次の段落を見つけてください:

mysql_insert_id() は、値が AUTO_INCREMENT カラムに格納されているかどうかに関係なく、AUTO_INCREMENT カラムに格納された値を返します。 NULL または 0 を格納することによって自動的に生成されるか、明示的な値として指定された LAST_INSERT_ID() は、NULL または 0 以外の明示的な値を格納する場合、LAST_INSERT_ID() によって返される値には影響しません。 🎜>

結論

マニュアルの説明から、テーブル内のフィールドが AUTO_INCREMENT 制約を使用していない場合、mysql_insert_id 関数はフィールドに格納されている値を返すことがわかります。 AUTO_INCREMENT 制約を使用するか、独自に生成された一意の値を使用する場合、関数は保存した値を返さず、代わりに NULL または 0 を返します。したがって、AUTO_INCREMENT 制約を使用しないテーブル、または ID が自己生成された一意の ID であるテーブルでは、lastInsertId 関数は 0 を返します。

この記事では問題の理由について説明していますが、私の個人的なレベルに限界があるため、ご提案やご批判がございましたら、お気軽にご指摘ください。

注: この記事では PHP5.4.15、MySQL5.5.41 を使用しています。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート