LAST_INSERT_ID () MySQL


151

J'ai une question MySQL qui, je pense, doit être assez simple. Je dois renvoyer le DERNIER ID INSÉRÉ de table1 lorsque j'exécute la requête MySql suivante:

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

Comme vous pouvez comprendre que le code actuel renverra simplement l'ID DERNIER INSERT de table2 au lieu de table1, comment puis-je obtenir l'ID de table1 même si je l'insère dans table2 entre?

Réponses:


249

Vous pouvez stocker le dernier identifiant d'insertion dans une 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);    

Ou obtenez le 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
Merci! Je ne l'ai pas fait fonctionner en premier car j'utilisais asp.net avec MySQL et devais ajouter Autoriser les variables utilisateur = True à la chaîne de connexion pour autoriser les variables.
Martin

114
max n'est pas une bonne idée, car vous pourriez perdre une course avec un autre inséreur.
Rob Starling

5
@RobStarling Je suis tout à fait d'accord, mais au cas où quelqu'un en aurait absolument besoin; utilisez une transaction avec le niveau d'isolement approprié.
Aidiakapi

8
et si 2 INSERTS se produisaient en même temps ou l'un avant l'autre?
FosAvance

32
@FosAvance LAST_INSERT_ID () est une référence
Gun2sh

18

Puisque vous avez en fait stocké le LAST_INSERT_ID () précédent dans la deuxième table, vous pouvez l'obtenir à partir de 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

Cela vous permet d'insérer une ligne dans 2 tables différentes et crée également une référence aux deux tables.

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
Bon cliché sur la transaction.
Kurt Van den Branden

1
Mais: uniquement disponible sur InnoDB.
raiserle

4

J'ai eu le même problème dans bash et je fais quelque chose comme ça:

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

qui fonctionne bien :-) Mais

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

ne marche pas. Parce qu'après la première commande, le shell sera déconnecté de mysql et à nouveau connecté pour la deuxième commande, puis la variable @last_insert_id n'est plus définie. Ma solution est:

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

Peut-être que quelqu'un cherche une solution un bash :-)


LAST_INSERT_IDdisponible uniquement pour la connexion active. #mysq-command connect pour chaque commande. Vous pouvez vous connecter avec la mysqlcommande au serveur et insérer vos requêtes, ou vous pouvez créer un fichier texte et vous la mysqlcommande avec redirection à partir du fichier txt akamysql [connection option] < txt.file
raiserle

1

Nous n'avons qu'une seule personne qui saisit les enregistrements, j'exécute donc la requête suivante immédiatement après l'insertion:

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

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

            $id = $row['id'];

}

Cela récupère le dernier identifiant de la base de données.


1
Je devais donner un exemple valide, alors j'ai utilisé celui que j'utilise. Si je l'avais fait en C, vous vous seriez probablement plaints "tout le monde n'utilise pas le C" ....
sspence65

Probablement le plus sûr et le plus simple de tous;)
Anjana Silva

1

Pour aucune solution InnoDB: vous pouvez utiliser une procédure 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

Et vous pouvez l'utiliser ...

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

0

Il serait possible de sauvegarder la variable last_id_in_table1 dans une variable php pour l'utiliser plus tard?

Avec ce last_id, je dois attacher des enregistrements dans une autre table avec ce last_id, j'ai donc besoin de:

1) Faites un INSERT et récupérez le last_id_in_table1

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

2) Pour toutes les lignes indéterminées d'une autre table, METTRE À JOUR ces lignes avec le last_id_insert généré dans l'insertion.

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


-1

Pour le dernier et l'avant-dernier:

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

Cette solution n'est pas sûre en dehors d'une transaction (c'est-à-dire que l'autocommit est activé) et à l'intérieur d'une transaction avec un niveau d'isolation de transaction inférieur à sérialisable. Voir: en.wikipedia.org/wiki/Isolation_(database_systems)
snorbi

-2

Juste pour ajouter pour Rodrigo post, au lieu de LAST_INSERT_ID () dans la requête, vous pouvez utiliser SELECT MAX (id) FROM table1;, mais vous devez utiliser (),

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

Cette solution n'est pas sûre en dehors d'une transaction (c'est-à-dire que l'autocommit est activé) et à l'intérieur d'une transaction avec un niveau d'isolation de transaction inférieur à sérialisable. Voir: en.wikipedia.org/wiki/Isolation_(database_systems)
snorbi

-9

Si vous avez besoin d'avoir de mysql, après votre requête, le dernier identifiant auto-incrémentiel sans autre requête, insérez votre code:

mysql_insert_id();

15
Ne pas recommander mysql_ * - ceux-ci sont obsolètes
German Rumm

cletus a obtenu 106 votes positifs et une réponse marquée pour mysql_insert_id ici: stackoverflow.com/a/897361/153923
jp2code

2
cletus y a répondu en 2009! mysql est obsolète, mieux vaut utiliser mysqli et mysqli_insert_id ie2.php.net/mysqli_insert_id
Maciej Paprocki

2
Luca, si vous supprimez cette réponse obsolète, je pense que vos points de réputation vous seront retournés.
TecBrat

Une autre alternative valide à la suggestion obsolète est PDO :: lastInsertId ( php.net/manual/en/pdo.lastinsertid.php )
w5m
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.