LAST_INSERT_ID () MySQL

151

Tengo una pregunta de MySQL que creo que debe ser bastante fácil. Necesito devolver la última ID INSERTADA de la tabla 1 cuando ejecuto la siguiente consulta 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();

Como puede entender, el código actual solo devolverá la ÚLTIMA ID DE INSERCIÓN de table2 en lugar de table1, ¿cómo puedo obtener la identificación de table1 incluso si inserto en table2 entre?

Martín
fuente

Respuestas:

248

Puede almacenar la última identificación de inserción en una variable:

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

O obtenga la ID máxima de 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;   
Julien Hoarau
fuente
55
¡Gracias! No lo hice funcionar primero porque estaba usando asp.net con MySQL y necesitaba agregar Permitir variables de usuario = Verdadero a la cadena de conexión para permitir variables.
Martin
114
max no es una buena idea, ya que podrías perder una carrera con otro insertador.
Rob Starling
55
@RobStarling Estoy totalmente de acuerdo, pero en caso de que alguien lo necesite absolutamente; use una transacción con el nivel de aislamiento adecuado.
Aidiakapi
8
¿Qué pasa si 2 INSERTOS ocurren al mismo tiempo o uno antes del otro?
FosAvance
32
@FosAvance LAST_INSERT_ID () es una referencia
Momin Al Aziz
18

Como realmente almacenó el LAST_INSERT_ID () anterior en la segunda tabla, puede obtenerlo desde allí:

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();
Artem Goutsoul
fuente
13

Esto le permite insertar una fila en 2 tablas diferentes y también crea una referencia a ambas tablas.

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;
Ospho
fuente
1
Buen disparo en la transacción.
Kurt Van den Branden
1
Pero: solo disponible en InnoDB.
Raiserle
4

Tuve el mismo problema en bash y estoy haciendo algo como esto:

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

que funciona bien :-) Pero

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

no trabajes Porque después del primer comando, el shell se cerrará sesión en mysql y se volverá a iniciar sesión para el segundo comando, y luego la variable @last_insert_id ya no estará configurada. Mi solución es:

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});"

Tal vez alguien está buscando una solución un bash :-)

Eugen Spinne
fuente
LAST_INSERT_IDsolo disponible para la conexión activa. #mysq-command conecta para cada comando. Puede conectarse con el mysqlcomando al servidor e insertar sus consultas, o puede crear un archivo de texto y usted el mysqlcomando con la redirección desde el archivo txt akamysql [connection option] < txt.file
raiserle
1

Solo tenemos una persona ingresando registros, por lo que ejecuto la siguiente consulta inmediatamente después de la inserción:

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

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

            $id = $row['id'];

}

Esto recupera la última identificación de la base de datos.

sspence65
fuente
1
Tenía que dar un ejemplo válido, así que usé el que uso. Si lo hubiera hecho en C, probablemente habría quejado "No todo el usos C" ....
sspence65
Probablemente el más seguro y simple de todos;)
Anjana Silva
1

Para ninguna solución de InnoDB: puede usar un procedimiento 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

Y puedes usarlo ...

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

¿Sería posible guardar la variable last_id_in_table1 en una variable php para usarla más tarde?

Con este last_id necesito adjuntar algunos registros en otra tabla con este last_id, así que necesito:

1) Haga un INSERT y obtenga el last_id_in_table1

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

2) Para cualquier fila indeterminada en otra tabla, ACTUALIZANDO estas filas con el last_id_insert generado en la inserción.

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

En lugar de esto, LAST_INSERT_ID() intente usar este

mysqli_insert_id(connection)
Sambit Kumar Dalai
fuente
-1

Para el último y el segundo último:

INSERT INTO `t_parent_user`(`u_id`, `p_id`) VALUES ((SELECT MAX(u_id-1) FROM user) ,(SELECT MAX(u_id) FROM user  ) );
usuario2541471
fuente
Esta solución no es segura fuera de una transacción (es decir, confirmación automática habilitada) y dentro de una transacción con un nivel de aislamiento de transacción por debajo de serializable. Ver: en.wikipedia.org/wiki/Isolation_(database_systems)
snorbi
-2

Solo para agregar para la publicación de Rodrigo, en lugar de LAST_INSERT_ID () en la consulta, puede usar SELECT MAX (id) FROM table1 ;, pero debe usar (),

INSERT INTO table1 (title,userid) VALUES ('test', 1)
INSERT INTO table2 (parentid,otherid,userid) VALUES ( (SELECT MAX(id) FROM table1), 4, 1)
Pavlen
fuente
Esta solución no es segura fuera de una transacción (es decir, confirmación automática habilitada) y dentro de una transacción con un nivel de aislamiento de transacción por debajo de serializable. Ver: en.wikipedia.org/wiki/Isolation_(database_systems)
snorbi
-9

Si necesita tener de mysql, después de su consulta, la última identificación incremental automática sin otra consulta, ingrese su código:

mysql_insert_id();
Luca Perico
fuente
15
No recomiendo mysql_ * - esos están en desuso
German Rumm
cletus obtuvo 106 votos a favor y marcó la respuesta para mysql_insert_id aquí: stackoverflow.com/a/897361/153923
jp2code
2
¡cletus lo respondió en 2009! mysql está en desuso mejor usar mysqli y mysqli_insert_id ie2.php.net/mysqli_insert_id
Maciej Paprocki
2
Luca, si eliminas esta respuesta desactualizada, creo que te devolverán tus puntos de reputación.
TecBrat
Otra alternativa válida a la sugerencia obsoleta es PDO :: lastInsertId ( php.net/manual/en/pdo.lastinsertid.php )
w5m