LAST_INSERT_ID () MySQL

151

Ich habe eine MySQL-Frage, die meiner Meinung nach recht einfach sein muss. Ich muss die LAST INSERTED ID aus Tabelle1 zurückgeben, wenn ich die folgende MySQL-Abfrage ausführe:

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

Wie Sie verstehen können, gibt der aktuelle Code nur die LAST INSERT-ID von Tabelle2 anstelle von Tabelle1 zurück. Wie kann ich die ID von Tabelle1 abrufen, selbst wenn ich zwischenzeitlich in Tabelle2 einfüge?

Martin
quelle

Antworten:

248

Sie können die letzte Einfügungs-ID in einer Variablen speichern:

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

Oder holen Sie sich die maximale ID aus Tabelle1

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
quelle
5
Vielen Dank! Ich habe es nicht zum ersten Mal zum Laufen gebracht, da ich asp.net mit MySQL verwendet habe und der Verbindungszeichenfolge Allow User Variables = True hinzufügen musste, um Variablen zuzulassen.
Martin
114
max ist keine gute Idee, da Sie ein Rennen mit einem anderen Inserter verlieren könnten.
Rob Starling
5
@RobStarling Ich stimme vollkommen zu, aber falls jemand es unbedingt braucht; Verwenden Sie eine Transaktion mit der richtigen Isolationsstufe.
Aidiakapi
8
Was ist, wenn 2 INSERTS gleichzeitig oder voreinander passiert sind?
FosAvance
32
@FosAvance LAST_INSERT_ID () ist verbindungsspezifisch ref
Momin Al Aziz
18

Da Sie die vorherige LAST_INSERT_ID () tatsächlich in der zweiten Tabelle gespeichert haben, können Sie sie von dort abrufen:

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
quelle
13

Auf diese Weise können Sie eine Zeile in zwei verschiedene Tabellen einfügen und einen Verweis auf beide Tabellen erstellen.

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
quelle
1
Guter Schuss bei der Transaktion.
Kurt Van den Branden
Aber: nur auf InnoDB verfügbar.
Raiserle
4

Ich hatte das gleiche Problem bei Bash und mache so etwas:

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

was gut funktioniert :-) Aber

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

arbeite nicht Denn nach dem ersten Befehl wird die Shell von MySQL abgemeldet und für den zweiten Befehl erneut angemeldet, und dann wird die Variable @last_insert_id nicht mehr gesetzt. Meine Lösung ist:

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

Vielleicht sucht jemand nach einer Lösung eine Bash :-)

Eugen Spinne
quelle
LAST_INSERT_IDNur für die aktive Verbindung verfügbar. #mysq-Befehlsverbindung für jeden Befehl. Sie können mit dem mysqlBefehl eine Verbindung zum Server herstellen und Ihre Abfragen einfügen, oder Sie können eine Textdatei erstellen und den mysqlBefehl mit Umleitung von der txt-Datei akamysql [connection option] < txt.file
raiserle
1

Wir haben nur eine Person, die Datensätze eingibt, daher führe ich die folgende Abfrage unmittelbar nach dem Einfügen aus:

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

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

            $id = $row['id'];

}

Dadurch wird die letzte ID aus der Datenbank abgerufen.

sspence65
quelle
1
Ich musste ein gültiges Beispiel geben, also habe ich das verwendet, das ich verwende. Wenn ich es in C gemacht hätte, hätten Sie sich wahrscheinlich beschwert "nicht jeder benutzt C" ....
sspence65
Wahrscheinlich die sicherste und einfachste von allen;)
Anjana Silva
1

Für keine InnoDB-Lösung: Sie können ein Verfahren verwenden 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

Und du kannst es benutzen ...

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

Ist es möglich, die Variable last_id_in_table1 in einer PHP-Variablen zu speichern, um sie später zu verwenden?

Mit dieser last_id muss ich einige Datensätze in einer anderen Tabelle mit dieser last_id anhängen, also brauche ich:

1) Machen Sie ein INSERT und holen Sie sich die last_id_in_table1

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

2) Für unbestimmte Zeilen in einer anderen Tabelle AKTUALISIEREN Sie diese Zeilen mit der in der Einfügung generierten last_id_insert.

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

LAST_INSERT_ID() Versuchen Sie stattdessen, diesen zu verwenden

mysqli_insert_id(connection)
Sambit Kumar Dalai
quelle
-1

Zum letzten und vorletzten:

INSERT INTO `t_parent_user`(`u_id`, `p_id`) VALUES ((SELECT MAX(u_id-1) FROM user) ,(SELECT MAX(u_id) FROM user  ) );
user2541471
quelle
Diese Lösung ist außerhalb einer Transaktion (dh Autocommit aktiviert) und innerhalb einer Transaktion mit einer Transaktionsisolationsstufe unter serialisierbar nicht sicher. Siehe: en.wikipedia.org/wiki/Isolation_(database_systems)
snorbi
-2

Nur um für Rodrigo-Post hinzuzufügen, können Sie anstelle von LAST_INSERT_ID () in der Abfrage SELECT MAX (id) FROM table1; verwenden, aber Sie müssen () verwenden,

INSERT INTO table1 (title,userid) VALUES ('test', 1)
INSERT INTO table2 (parentid,otherid,userid) VALUES ( (SELECT MAX(id) FROM table1), 4, 1)
Pavlen
quelle
Diese Lösung ist außerhalb einer Transaktion (dh Autocommit aktiviert) und innerhalb einer Transaktion mit einer Transaktionsisolationsstufe unter serialisierbar nicht sicher. Siehe: en.wikipedia.org/wiki/Isolation_(database_systems)
snorbi
-9

Wenn Sie nach Ihrer Abfrage die letzte automatisch inkrementelle ID ohne weitere Abfrage von MySQL benötigen, geben Sie Ihren Code ein:

mysql_insert_id();
Luca Perico
quelle
15
Nicht empfehlen mysql_ * - die sind veraltet
Deutsch Rumm
Cletus hat 106 Upvotes und eine markierte Antwort für mysql_insert_id hier erhalten: stackoverflow.com/a/897361/153923
jp2code
2
Cletus hat es 2009 beantwortet! mysql ist besser veraltet, um mysqli und mysqli_insert_id zu verwenden ie2.php.net/mysqli_insert_id
Maciej Paprocki
2
Luca, wenn Sie diese veraltete Antwort löschen, werden Ihre Reputationspunkte meiner Meinung nach zurückgegeben.
TecBrat
Eine andere gültige Alternative zu dem veralteten Vorschlag ist PDO :: lastInsertId ( php.net/manual/en/pdo.lastinsertid.php )
w5m