mysqlの挿入クエリから新しいレコードの主キーIDを取得しますか?


249

[OK]を、私はMySQLをやっていると言うことができますINSERT私のテーブルの一つに、テーブルには列があるitem_idに設定されているautoincrementprimary key

item_id同じクエリで新しく生成された主キーの値を出力するクエリを取得するにはどうすればよいですか?

現在、IDを取得するために2番目のクエリを実行していますが、これが間違った結果を生成する可能性があることを考えると、これは良い習慣とは思えません...

これが不可能な場合、正しいIDを確実に取得するためのベストプラクティスは何ですか?


1
このINSERTようなクエリから何かを返す方法はありません。なぜそれが間違った結果をもたらすかもしれないと思いますか?
爆発の丸薬2013年

4
さて、プロセスが2人で別々に実行されると、重複するプロセスリストを取得する可能性があります。2つの個別のクエリを実行する必要があるためでしょうか。
エイミーネヴィル


@JimFellはい、それは基本的に同じ質問ですが、これは一般的にはるかに優れた答えを持っています
RozzA

1
postgresqlを使用して、このINSERT INTO table(col1、col2)VALUES(val1、val2)RETURNING idまたはINSERT INTO table(col1、col2)VALUES(val1、val2)RETURNING *またはUPDATE table SET col1 = val1、col2 = val2 WHEREステートメントRETURNING idまたはUPDATE table SET(col1、col2)=(val1、val2)WHEREステートメントRETURNING idまたはUPDATE table SET(col1、col2)=(val1、val2)WHEREステートメントRETURNING *
gdarcan

回答:


326

LAST_INSERT_ID()関数を使用する必要があります:http : //dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

例えば:

INSERT INTO table_name (col1, col2,...) VALUES ('val1', 'val2'...);
SELECT LAST_INSERT_ID();

これPRIMARY KEYにより、挿入した最後の行の値が返さます

生成されたIDは、接続ごとにサーバーで維持されます。つまり、関数から特定のクライアントに返される値は、そのクライアントによって AUTO_INCREMENT列に影響を与える最新のステートメントに対して生成された最初のAUTO_INCREMENT値です

したがって、によって返される値はLAST_INSERT_ID()ユーザーごとであり、サーバー上で他のユーザーから実行されている可能性のある他のクエリの影響を受けません


8
はい。ただし、その途中(プロセスリストのクエリ間)に他の行が挿入された場合はどうなりますか?これを出力するように挿入クエリを書く方法はありますか?
エイミーネヴィル

わかりました。クエリの最後の挿入IDは、結果にログインしていなくても記録されます... $ mysqli-> insert_id
Amy Neville

27
これは、あなたが戻ってきますPRIMARY KEYことを、最後の行の値あなたは、サーバーへの各接続は、このためにそれ自身の価値を維持します-それは、接続ごとのだから、挿入します。これを明確にするために、回答を更新しました。
Duncan Lock

したがって、3人のユーザーが同時にフォームを投稿し、私のデータベースがそれらを入力する必要があるとします。新しく作成されたtable1の各IDに対応する行をtable2に追加したい。並行処理は行われるのですか、それともPHPで手動で行う必要がありますか?
bad_keypoints 2013

table1の挿入を実行した時点で、データベースがtable2に挿入するすべての情報を認識している場合は、トリガーを使用してこれを実行するか、これをクエリに結合できます。そうでない場合は、複数のクエリを使用する必要があります。つまり、PHPで実行します。これは、データが何であるか、および2番目の挿入でどこから取得されるかによって異なります。
Duncan Lock

21

注意してください! PHP内でこの主キーの値を返そうとする場合、「LAST_INSERT_ID()」

私はこのスレッドにphpのタグが付いていないことを知っていますが、標準のmysql_query呼び出しを使用してPHPスクリプト挿入からMySQL挿入IDを返そうとしているこの回答に出くわした人は、SQLエラーをキャプチャしないと機能せず、明白ではありません。

新しいmysqliは複数のクエリをサポートします -LAST_INSERT_ID()は実際には元のクエリの2番目のクエリです。

最後の主キーを識別する別のSELECTをIMOすることは、前のINSERT操作で生成されたAUTO_INCREMENT IDを返すオプションのmysql_insert_id()関数より安全です。


7
LAST_INSERT_ID接続ごとのMySQL関数です。最後の挿入IDを照会すると、別の接続が書き込みを実行し、IDが間違っている可能性があります。
爆発の丸薬2014

@ExplosionPillsはmysql_insert_id()また、接続ごとに動作しますが、ここに見られるように、それはまた、奇妙な行動を被るstackoverflow.com/a/897374/1305910 Cliffordlifeでコメントで-用事我々はすべて使用されている必要がありますmysqli
RozzA

あなたが「それがうまくいかない」ままでいるとき、あなたが何を意味するのかを明確にすることができますか?
john ktejik

18

LAST_INSERT_ID()ドキュメントから:

生成されたIDは、接続ごとにサーバーで維持されます。

つまり、スクリプトへの2つの別々の要求が同時にある場合、それらは互いに影響しませんLAST_INSERT_ID()(持続的な接続を使用している場合を除きます)。


2
私は...あなたのテーブルが別のテーブルへの挿入を行い、その上にトリガを持っている場合.... LAST_INSERT_ID()は、他のテーブルのid値を返します怪しげだと思う
bgies

15

ここであなたが探しているもの!!!

select LAST_INSERT_ID()

これは、SCOPE_IDENTITY()で使用されている関数の最良の選択肢ですSQL Server

また、これはLast_INSERT_ID()Insertクエリによって起動された場合にのみ機能することにも注意してください。つまり、クエリはスキーマに挿入されたIDを返します。特定のテーブルの最後に挿入されたIDを取得できません。

詳細については、リンクを参照してくださいmySQLのSQLServer関数SCOPE_IDENTITY()と同等ですか?


6

行を挿入する前に値が必要な場合:

CREATE FUNCTION `getAutoincrementalNextVal`(`TableName` VARCHAR(50))
    RETURNS BIGINT
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

    DECLARE Value BIGINT;

    SELECT
        AUTO_INCREMENT INTO Value
    FROM
        information_schema.tables
    WHERE
        table_name = TableName AND
        table_schema = DATABASE();

    RETURN Value;

END

これを挿入で使用できます:

INSERT INTO
    document (Code, Title, Body)
VALUES (                
    sha1( concat (convert ( now() , char), ' ',   getAutoincrementalNextval ('document') ) ),
    'Title',
    'Body'
);

1
これは良い考えではないようですか?2つのクライアントが同時にその関数を呼び出すと、実際にはそうではないのに、同じIDを挿入していると考えられます。
CarCar 2017

5

クエリ結果でこれらのパラメーターを受け取ります。

    "fieldCount": 0,
    "affectedRows": 1,
    "insertId": 66,
    "serverStatus": 2,
    "warningCount": 1,
    "message": "",
    "protocol41": true,
    "changedRows": 0

insertIdあなたが必要とする正確に何です。

(NodeJS-mySql)


4

Pythonでpymysqlを使用している場合、カーソルからcursor.lastrowidを使用できます


2

単に「$ last_id = mysqli_insert_id($ conn);」を使用してください


2
私は実際にグーグルのおかげでこの回答のphpバージョンを探してここでつまずいたので、この回答に投票しました。技術的には、OPはphpを要求しませんでしたが、これは、ここでつまずく多くの人々にとっても役立ちます。
写真家Britt 2018

Arnavさん、ありがとうございました!I
JuanSedano



0

私はこれに対する私のアプローチをPHPで共有したいと思います。効率的な方法ではないかもしれませんが、これは他の利用可能なオプションよりも100優れています。

ランダムキーを生成し、それをテーブルに挿入して新しい行を作成します。次に、そのキーを使用して主キーを取得できます。更新を使用してデータを追加し、他のことを行います。

この方法を使用すると、行を保護し、正しい主キーを取得するのに役立ちます。

他のオプションがない限り、私はこれを実際にお勧めしません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.