LAST_INSERT_ID() MySQL

180

我有一个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();

您可以理解,当前代码只会返回table2的最新插入ID,而不是table1的。那么,即使在插入table2之间,如何获取来自table1的ID?

14个回答

299

您可以将最后一个插入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);    

从table1获取最大id(编辑:警告。请查看Rob Starling在评论中关于使用最大id可能出现的竞争条件错误的说明)

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;  

(警告:正如Rob Starling在评论中指出的那样)


6
谢谢!一开始我的asp.net和MySQL没能配合成功,后来我才发现需要在连接字符串中添加Allow User Variables=True才能允许使用变量。 - Martin
136
"Max不是一个好主意,因为你可能会在与另一个插入器的比赛中失利。" - Rob Starling
5
@RobStarling,我完全同意,但如果有人绝对需要,可以使用具有适当隔离级别的事务。 - Aidiakapi
8
如果两个INSERT同时发生或一个在另一个之前发生会怎样? - FosAvance
42
@FosAvance LAST_INSERT_ID() 是与连接相关的参考链接 - Gun2sh
显示剩余6条评论

25

由于您实际上将前一个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();

15

这使您能够将一行插入到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

6

我在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);"

不起作用。因为第一条命令执行后,shell 将从 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寻找解决方案 :-)

1
LAST_INSERT_ID only available for the active connection. #mysq-command connect for every command. You can connect with the mysql command to the server and insert your queries, or you can create a text file and you the mysql command with redirect from txt file aka mysql [connection option] < txt.file - raiserle

1

如果没有InnoDB解决方案:您可以使用一个存储过程 不要忘记设置分隔符以便使用; 存储过程

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;

1
在BEFORE_INSERT触发器中,这对我有用:
SET @Last_Insrt_Id = (SELECT(AUTO_INCREMENT /*-1*/) /*as  Last_Insert_Id*/ 
FROM information_schema.tables 
WHERE table_name = 'tblTableName' AND table_schema = 'schSchemaName');

或者简单选择:

SELECT(AUTO_INCREMENT /*-1*/) as Last_Insert_Id
FROM information_schema.tables 
WHERE table_name = 'tblTableName' AND table_schema = 'schSchemaName'); 

如果您想要的话,可以移除注释/*-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

能否将last_id_in_table1变量保存到php变量中以便以后使用?

有了这个last_id,我需要将一些记录附加到另一个表中,所以我需要:

1)进行插入并获取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

不要使用 LAST_INSERT_ID(),尝试使用这个

mysqli_insert_id(connection)

0

我们也可以使用 $conn->insert_id; // 创建连接

    $conn = new mysqli($servername, $username, $password, $dbname);
    $sql = "INSERT INTO MyGuests (firstname, lastname, email)
    VALUES ('John', 'Doe', 'john@example.com')";

    if ($conn->query($sql) === TRUE) {
        $last_id = $conn->insert_id;
        echo "New record created successfully. Last inserted ID is: " . $last_id;
    } else {
        echo "Error: " . $sql . "<br>" . $conn->error;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接