44

単一のレコード挿入を実行するループで複数のレコードを挿入すると、予想どおり、最後に返される挿入IDが最後の挿入IDになります。しかし、複数のレコードを挿入する場合は、次のステートメントを挿入します。

INSERT INTO people (name,age)
VALUES ('William',25), ('Bart',15), ('Mary',12);

上記の3つがテーブルに挿入された最初のレコードであるとしましょう。挿入ステートメントの後、最後の挿入IDが3を返すことを期待していましたが、1を返しました。問題のステートメントの最初の挿入ID。

LAST_INSERT_ID()したがって、これが複数のレコードのINSERTステートメントのコンテキストでの正常な動作であるかどうかを誰かが確認できますか。だから私はそれに基づいてコードを書くことができます。

4

3 に答える 3

47

はい。のこの動作はlast_insert_id()MySQLドキュメントに記載されています

重要
単一のINSERTステートメントを使用して複数の行を挿入する場合LAST_INSERT_ID()、最初に挿入された行に対してのみ生成された値を返します。INSERTこれは、他のサーバーに対して同じステートメントを簡単に再現できるようにするためです。

于 2011-10-31T21:00:47.557 に答える
2

この動作は、MySQLのマニュアルページに記載されています。コメントにありますが、チャレンジされていないので、予想通りの動作だと思います。

于 2011-01-09T03:44:38.883 に答える
2

テーブルに一意の自動インクリメント列(ID)があり、mysql自体によって返される必要がない場合は可能だと思います。さらに3つのDBリクエストといくつかの処理が必要になります。次の手順が必要になります。

  1. 挿入の直前に「BeforeMAX(ID)」を取得します。
    SELECT MAX(id) AS before_max_id FROM table_name`
  1. データを使用して複数のINSERT...VALUES()クエリを作成し、それらを保持します。

    INSERT INTO table_name
    (col1, col2)
    VALUES 
    ("value1-1" , "value1-2"), 
    ("value2-1" , "value2-2"), 
    ("value3-1" , "value3-2"), 
    ON DUPLICATE KEY UPDATE
    
  2. 挿入直後に「AfterMAX(ID)」を取得します。

    SELECT MAX(id) AS after_max_id FROM table_name`
    
  3. 次のような「BeforeMAX(ID)」と「AfterMAX(ID)」の間のIDを持つレコードを取得します。

    SELECT * FROM table_name WHERE id>$before_max_id AND id<=$after_max_id`
    
  4. 取得したデータを挿入したデータと一致するようにチェックし、挿入されなかったレコードをすべて削除します。残りのレコードにはIDがあります。

    foreach ($after_collection as $after_item) {
      foreach ($input_collection as $input_item) {
        if ( $after_item->compare_content($input_item) ) {
          $intersection_array[] = $after_item;
        }
      }
    }

これは、一般の人がコードの一部を使用して、現実の世界でそれを解決する方法です。自動インクリメントのおかげで、チェックするレコードの量を可能な限り少なくする必要があるため、多くの処理を行う必要はありません。これは、最終的な「コピーアンドペースト」コードではありません。必要に応じて、独自の関数compare_content()を作成する必要があります。

于 2018-09-21T14:16:23.220 に答える