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?

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;   

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

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;

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


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.


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;

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 
    }


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

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)

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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.