LAST_INSERT_ID () MySQL


151

Ho una domanda su MySQL che penso debba essere abbastanza semplice. Devo restituire l'ID ULTIMO INSERITO dalla tabella 1 quando eseguo la seguente query 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();

Come puoi capire, il codice corrente restituirà l'ID ULTIMO INSERTO di table2 invece di table1, come posso ottenere l'id da table1 anche se inserisco in table2 tra?

Risposte:


249

È possibile memorizzare l'ultimo ID di inserimento in una variabile:

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

Oppure ottieni l'id massimo dalla tabella1

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
Grazie! Non l'ho fatto funzionare prima mentre stavo usando asp.net con MySQL e dovevo aggiungere Consenti variabili utente = Vero alla stringa di connessione per consentire le variabili.
Martin,

114
max non è una buona idea, in quanto potresti perdere una gara con un altro inseritore.
Rob Starling

5
@RobStarling Sono pienamente d'accordo, ma nel caso qualcuno ne abbia assolutamente bisogno; utilizzare una transazione con il livello di isolamento adeguato.
Aidiakapi,

8
cosa succede se 2 INSERTI accadono contemporaneamente o uno prima dell'altro?
FosAvance,

32
@FosAvance LAST_INSERT_ID () è connessione specifica ref
Gun2sh

18

Poiché in realtà hai archiviato il precedente LAST_INSERT_ID () nella seconda tabella, puoi ottenerlo da lì:

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

Ciò consente di inserire una riga in 2 tabelle diverse e di creare un riferimento anche per entrambe le tabelle.

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
Ottimo scatto sulla transazione.
Kurt Van den Branden,

1
Ma: disponibile solo su InnoDB.
Raiserle,

4

Ho avuto lo stesso problema in bash e sto facendo qualcosa del genere:

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

che funziona benissimo :-) Ma

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

non funziona. Perché dopo il primo comando, la shell verrà disconnessa da mysql e ricollegata per il secondo comando, quindi la variabile @last_insert_id non sarà più impostata. La mia soluzione è:

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

Forse qualcuno è alla ricerca di una soluzione un bash :-)


LAST_INSERT_IDdisponibile solo per la connessione attiva. #mysq-command connect per ogni comando. Puoi connetterti con il mysqlcomando al server e inserire le tue query, oppure puoi creare un file di testo e il mysqlcomando con reindirizzamento dal file txt akamysql [connection option] < txt.file
raiserle

1

Abbiamo solo una persona che inserisce i record, quindi eseguo la seguente query immediatamente dopo l'inserimento:

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

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

            $id = $row['id'];

}

Ciò recupera l'ultimo ID dal database.


1
Ho dovuto dare un esempio valido, quindi ho usato quello che uso. Se l'avessi fatto in C, probabilmente ti saresti lamentato "non tutti usano C" ....
sspence65

Probabilmente il più sicuro e il più semplice di tutti;)
Anjana Silva l'

1

Per nessuna soluzione InnoDB: è possibile utilizzare una procedura 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

E puoi usarlo ...

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

0

Sarebbe possibile salvare la variabile last_id_in_table1 in una variabile php per usarla in seguito?

Con questo last_id ho bisogno di allegare alcuni record in un'altra tabella con questo last_id, quindi ho bisogno di:

1) Fai un INSERT e ottieni last_id_in_table1

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

2) Per qualsiasi riga indeterminata in un'altra tabella, AGGIORNAMENTO di queste righe con last_id_insert generato nell'inserto.

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


-1

Per l'ultimo e il secondo ultimo:

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

Questa soluzione non è sicura al di fuori di una transazione (ovvero autocommit abilitato) e all'interno di una transazione con un livello di isolamento della transazione inferiore a serializzabile. Vedi: en.wikipedia.org/wiki/Isolation_(database_systems)
snorbi

-2

Solo per aggiungere per il post Rodrigo, invece di LAST_INSERT_ID () nella query puoi usare SELECT MAX (id) FROM table1 ;, ma devi usare (),

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

Questa soluzione non è sicura al di fuori di una transazione (ovvero abilitato per autocommit) e all'interno di una transazione con un livello di isolamento della transazione inferiore a serializzabile. Vedi: en.wikipedia.org/wiki/Isolation_(database_systems)
snorbi

-9

Se devi avere da mysql, dopo la tua query, l'ultimo ID auto-incrementale senza un'altra query, inserisci il tuo codice:

mysql_insert_id();

15
Non raccomandare mysql_ * - quelli sono deprecati
Rumm tedesco

Cletus ha ottenuto 106 upvotes e segnato risposta per mysql_insert_id qui: stackoverflow.com/a/897361/153923
jp2code

2
Cletus ha risposto nel 2009! mysql è deprecato meglio per usare mysqli e mysqli_insert_id ie2.php.net/mysqli_insert_id
Maciej Paprocki

2
Luca, se eliminerai questa risposta obsoleta, credo che i tuoi punti reputazione verranno restituiti.
TecBrat,

Un'altra valida alternativa al suggerimento deprecato è PDO :: lastInsertId ( php.net/manual/en/pdo.lastinsertid.php )
W5M
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.