LAST_INSERT_ID () MySQL


151

ฉันมีคำถาม MySQL ที่ฉันคิดว่าต้องง่ายมาก ฉันต้องส่งคืน LAST INSERTED ID จาก table1 เมื่อฉันเรียกใช้แบบสอบถาม MySql ต่อไปนี้:

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

ในขณะที่คุณสามารถเข้าใจว่ารหัสปัจจุบันจะส่งคืน LAST INSERT ID ของ table2 แทน table1 ฉันจะรับ id จาก table1 ได้อย่างไรแม้ว่าฉันจะแทรกเข้าไปใน table2

คำตอบ:


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
ขอบคุณ! ฉันไม่ได้ทำงานก่อนเพราะฉันใช้ asp.net กับ MySQL และจำเป็นต้องเพิ่ม Allow User Variables = True ให้กับสตริงการเชื่อมต่อเพื่ออนุญาตตัวแปร
Martin

114
แม็กซ์ไม่ใช่ความคิดที่ดีเพราะคุณอาจแพ้การแข่งขันกับผู้สอดแทรกอีกคน
Rob Starling

5
@ RobStarling ฉันเห็นด้วย แต่ในกรณีที่มีคนต้องการมัน; ใช้ธุรกรรมที่มีระดับการแยกที่เหมาะสม
Aidiakapi

8
จะเกิดอะไรขึ้นถ้า 2 INSERTS เกิดขึ้นพร้อมกันหรือต่อหน้ากัน?
FosAvance

32
@FosAvance LAST_INSERT_ID () เป็นการอ้างอิง
Gun2sh

18

เนื่องจากคุณเก็บ LAST_INSERT_ID () ก่อนหน้านี้ไว้ในตารางที่สองคุณสามารถรับได้จากที่นั่น:

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 เท่านั้น
raiserle

4

ฉันมีปัญหาเดียวกันในการทุบตีและฉันกำลังทำสิ่งนี้:

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 และล็อกอินอีกครั้งสำหรับคำสั่งที่สองจากนั้นตัวแปร @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คำสั่งเชื่อมต่อสำหรับทุกคำสั่ง คุณสามารถเชื่อมต่อกับmysqlคำสั่งไปยังเซิร์ฟเวอร์และแทรกคำสั่งของคุณหรือคุณสามารถสร้างไฟล์ข้อความและคุณmysqlคำสั่งด้วยการเปลี่ยนเส้นทางจากไฟล์ txt akamysql [connection option] < txt.file
raiserle

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

สำหรับสุดท้ายและวินาทีสุดท้าย:

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)
snorbi

-2

เพียงเพิ่มสำหรับโพสต์ Rodrigo แทน LAST_INSERT_ID () ในแบบสอบถามคุณสามารถใช้ SELECT MAX (id) จาก 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)
snorbi

-9

หากคุณต้องการจาก mysql หลังจากการสอบถามของคุณ id อัตโนมัติที่เพิ่มขึ้นล่าสุดโดยไม่ต้องมีแบบสอบถามอื่นใส่รหัสของคุณ:

mysql_insert_id();

15
ไม่แนะนำ mysql_ * - สิ่งเหล่านี้ถูกคัดค้าน
German Rumm

cletusมี 106 upvotes และคำตอบที่ทำเครื่องหมายไว้สำหรับ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

2
Luca หากคุณจะลบคำตอบที่ล้าสมัยนี้ฉันเชื่อว่าคะแนนชื่อเสียงของคุณจะถูกส่งคืน
TecBrat

ทางเลือกอื่นที่ถูกต้องสำหรับข้อเสนอแนะที่เลิกใช้คือ PDO :: lastInsertId ( php.net/manual/en/pdo.lastinsertid.php )
w5m
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.