LAST_INSERT_ID()MySQL


151

MySQLの質問があるので、とても簡単だと思います。次のMySqlクエリを実行すると、table1から最後に挿入されたIDを返す必要があります。

INSERT INTO table1 (title,userid) VALUES ('test',1); 
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(),4,1);
SELECT LAST_INSERT_ID();

現在のコードがtable1ではなくtable2のLAST INSERT IDを返すだけであることを理解できるので、table2の間に挿入した場合でも、table1からIDを取得するにはどうすればよいですか?

回答:


248

最後の挿入IDを変数に格納できます。

INSERT INTO table1 (title,userid) VALUES ('test', 1); 
SET @last_id_in_table1 = LAST_INSERT_ID();
INSERT INTO table2 (parentid,otherid,userid) VALUES (@last_id_in_table1, 4, 1);    

または、max id frm table1を取得します

INSERT INTO table1 (title,userid) VALUES ('test', 1); 
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(), 4, 1); 
SELECT MAX(id) FROM table1;   

5
ありがとう!MySQLでasp.netを使用していて、変数を許可するために接続文字列にAllow User Variables = Trueを追加する必要があったので、最初は機能しませんでした。
Martin

114
maxは、別の挿入子との競合を失う可能性があるため、良い考えではありません。
Rob Starling 2013年

5
@RobStarling私は完全に同意しますが、誰かが絶対にそれを必要とする場合に備えて。適切な分離レベルでトランザクションを使用します。
アイディアカピ2013年

8
2つのINSERTが同時に発生した場合、または1つ前に発生した場合はどうなりますか?
FosAvance 2013年

32
@FosAvance LAST_INSERT_ID()は接続固有の参照です
Momin Al Aziz

18

前のLAST_INSERT_ID()を2番目のテーブルに実際に格納したので、そこから取得できます。

INSERT INTO table1 (title,userid) VALUES ('test',1); 
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(),4,1);
SELECT parentid FROM table2 WHERE id = LAST_INSERT_ID();

13

これにより、2つの異なるテーブルに行を挿入し、両方のテーブルへの参照も作成できます。

START TRANSACTION;
INSERT INTO accounttable(account_username) 
    VALUES('AnAccountName');
INSERT INTO profiletable(profile_account_id) 
    VALUES ((SELECT account_id FROM accounttable WHERE account_username='AnAccountName'));
    SET @profile_id = LAST_INSERT_ID(); 
UPDATE accounttable SET `account_profile_id` = @profile_id;
COMMIT;

1
トランザクションの良いショット。
Kurt Van den Branden

1
ただし、InnoDBでのみ使用できます。
ライザー

4

私はbashで同じ問題を抱えていて、私はこのようなことをしています:

mysql -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');"

それはうまくいきます:-)しかし

mysql -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');set @last_insert_id = LAST_INSERT_ID();"
mysql -D "dbname" -e "insert into table2 (id_tab1) values (@last_insert_id);"

動作しません。最初のコマンドの後、シェルはmysqlからログアウトされ、2番目のコマンドで再度ログインされます。その後、変数@last_insert_idが設定されなくなります。私の解決策は:

lastinsertid=$(mysql -B -N -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');select LAST_INSERT_ID();")
mysql -D "dbname" -e "insert into table2 (id_tab1) values (${lastinsertid});"

多分誰かがbashの解決策を探しています:-)


LAST_INSERT_IDアクティブな接続でのみ使用できます。#mysq-commandすべてのコマンドに接続します。mysqlコマンドを使用してサーバーに接続し、クエリを挿入するか、テキストファイルを作成してmysqlコマンドをtxtファイルからリダイレクトすることもできますmysql [connection option] < txt.file
raiserle

1

レコードを入力するのは1人だけなので、挿入の直後に次のクエリを実行します。

$result = $conn->query("SELECT * FROM corex ORDER BY id DESC LIMIT 1");

while ($row = $result->fetch_assoc()) {

            $id = $row['id'];

}

これにより、データベースから最後のIDが取得されます。


1
有効な例を挙げなければならなかったので、私が使用しているものを使用しました。私がCでそれを行ったとしたら、おそらく「すべての人がCを使用しているわけではない」と不平を言ったことでしょう...
sspence65

おそらく最も安全で最も単純な;)
Anjana Silva

1

InnoDBソリューションがない場合:プロシージャを使用できます don't forgot to set the the delimiter for storing the procedure with ;

CREATE PROCEDURE myproc(OUT id INT, IN otherid INT, IN title VARCHAR(255))
BEGIN
LOCK TABLES `table1` WRITE;
INSERT INTO `table1` ( `title` ) VALUES ( @title ); 
SET @id = LAST_INSERT_ID();
UNLOCK TABLES;
INSERT INTO `table2` ( `parentid`, `otherid`, `userid` ) VALUES (@id, @otherid, 1); 
END

そして、あなたはそれを使うことができます...

SET @myid;
CALL myproc( @myid, 1, "my title" );
SELECT @myid;

0

last_id_in_table1変数をphp変数に保存して後で使用することはできますか?

このlast_idを使用して、このlast_idで別のテーブルのレコードをアタッチする必要があるため、次のものが必要です。

1)INSERTを実行して、last_id_in_table1を取得します

INSERT into Table1(name) values ("AAA"); 
SET @last_id_in_table1 = LAST_INSERT_ID();

2)別のテーブルの不確定な行については、挿入で生成されたlast_id_insertを使用してこれらの行を更新します。

$element = array(some ids)    
foreach ($element as $e){ 
         UPDATE Table2 SET column1 = @last_id_in_table1 WHERE id = $e 
    }


-1

最後と2番目の場合:

INSERT INTO `t_parent_user`(`u_id`, `p_id`) VALUES ((SELECT MAX(u_id-1) FROM user) ,(SELECT MAX(u_id) FROM user  ) );

このソリューションは、トランザクションの外部(つまり、自動コミットが有効)やトランザクションの分離レベルがシリアライズ可能未満のトランザクションの内部では安全ではありません。参照:en.wikipedia.org/wiki/Isolation_
database_systems

-2

ロドリゴの投稿を追加するために、クエリでLAST_INSERT_ID()の代わりにSELECT MAX(id)FROM table1;を使用できますが、()を使用する必要があります。

INSERT INTO table1 (title,userid) VALUES ('test', 1)
INSERT INTO table2 (parentid,otherid,userid) VALUES ( (SELECT MAX(id) FROM table1), 4, 1)

このソリューションは、トランザクションの外部(つまり、自動コミットが有効)やトランザクションの分離レベルがシリアライズ可能未満のトランザクションの内部では安全ではありません。参照:en.wikipedia.org/wiki/Isolation_
database_systems

-9

mysqlから取得する必要がある場合は、クエリの後に、別のクエリのない最後の自動増分IDをコードに追加します。

mysql_insert_id();

15
mysql_ *はお勧めしません-これらは非推奨です
German Rumm

cletusは106の賛成票を獲得し、mysql_insert_idの回答をここにマークしました:stackoverflow.com/a/897361/153923
jp2code

2
cletusは2009年にそれを阻止しました!mysqlは非推奨になり、mysqliおよびmysqli_insert_id ie2.php.net/mysqli_insert_id
Maciej Paprocki 14年

2
ルカ、この古い回答を削除すると、評判ポイントが戻ってくると思います。
TecBrat 14

非推奨の提案に対する別の有効な代替案は、PDO :: lastInsertId(php.net/manual/en/pdo.lastinsertid.php
w5m
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.