Wie erhalte ich die ID der letzten aktualisierten Zeile in MySQL mit PHP?
Wie bekomme ich die ID der letzten aktualisierten Zeile in MySQL?
Avinash
Pomyk
Ich habe eine Antwort auf dieses Problem gefunden 🙂
SET @update_id := 0;
UPDATE some_table SET column_name="value", id = (SELECT @update_id := id)
WHERE some_other_column = 'blah' LIMIT 1;
SELECT @update_id;
BEARBEITEN von aefxx
Diese Technik kann weiter ausgebaut werden, um die ID jeder Zeile abzurufen, die von einer Update-Anweisung betroffen ist:
SET @uids := null;
UPDATE footable
SET foo = 'bar'
WHERE fooid > 5
AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;
Dies gibt eine Zeichenfolge mit allen IDs zurück, die durch ein Komma verkettet sind.
-
Ich kann nicht glauben, dass dies 0 positive Stimmen hatte, und der mysql_insert_id () -Kommentar, nach dem das OP überhaupt nicht gefragt hat, hat 13. Danke, Pomyk, ein cleverer Trick!
– Jaka Jančar
11. Januar 2011 um 15:47 Uhr
-
Da hast du eine
WHERE
Klausel können Sie einfach die gleiche verwendenWHERE
Klausel in Ihrer nächsten AbfrageSELECT id FROM footable WHERE fooid > 5
– Salmann A
15. Juli 2011 um 7:08 Uhr
-
Vielleicht versteht das jeder, aber wenn Sie mysql_query(); Sie müssen dies in drei verschiedene Anrufe aufteilen, aber es wird funktionieren.
– rael_kid
15. Mai 2012 um 10:15 Uhr
-
Es ist nicht einmal notwendig, Variablen zu verwenden.
LAST_INSERT_ID()
kann ein Argument akzeptieren, das den vom nächsten Aufruf zurückgegebenen Wert auf setztLAST_INSERT_ID()
. Zum Beispiel:UPDATE table SET id=LAST_INSERT_ID(id), row='value' WHERE other_row='blah';
. Jetzt,SELECT LAST_INSERT_ID();
gibt die aktualisierte ID zurück. Weitere Informationen finden Sie in der Antwort von newtover.– Joel
2. Juni 2014 um 14:35 Uhr
-
@SteveChilds Ich habe gerade die Frage von Newtover kommentiert und möchte eine Lösung für die von Ihnen beschriebene Falle hinzufügen. Dies setzt LAST_INSERT_ID auf 0, wenn es nichts zu UPDATE gibt:
UPDATE lastinsertid_test SET row='value' WHERE row='asd' AND LAST_INSERT_ID(id) OR LAST_INSERT_ID(0);
. Es werden jedoch nicht mehrere IDs abgerufen, daher ist diese Antwort überlegen.– Martinczerwi
29. April 2015 um 8:35 Uhr
neu
Hm, ich bin überrascht, dass ich unter den Antworten nicht die einfachste Lösung sehe.
Annehmen, item_id
ist eine ganzzahlige Identitätsspalte in items
Tabelle und Sie aktualisieren Zeilen mit der folgenden Anweisung:
UPDATE items
SET qwe="qwe"
WHERE asd = 'asd';
Um dann die letzte betroffene Zeile direkt nach der Anweisung zu kennen, sollten Sie die Anweisung leicht wie folgt aktualisieren:
UPDATE items
SET qwe="qwe",
item_id=LAST_INSERT_ID(item_id)
WHERE asd = 'asd';
SELECT LAST_INSERT_ID();
Wenn Sie nur wirklich geänderte Zeilen aktualisieren müssen, müssen Sie eine bedingte Aktualisierung der item_id durch die LAST_INSERT_ID hinzufügen, um zu prüfen, ob sich die Daten in der Zeile ändern werden.
-
Es ist für mehrere Benutzer sicher, da mehrere Clients die UPDATE-Anweisung absetzen und ihren eigenen Sequenzwert mit der SELECT-Anweisung (oder mysql_insert_id()) erhalten können, ohne andere Clients zu beeinflussen oder von ihnen beeinflusst zu werden, die ihre eigenen Sequenzwerte generieren. Gem dev.mysql.com/doc/refman/5.0/en/…
– Brutuskatze
21. April 2014 um 14:16 Uhr
-
Wird dadurch die item_id nicht auf den zuletzt eingefügten Datensatz gesetzt?
– Arleslie
2. August 2014 um 0:03 Uhr
-
@arleslie, wenn Sie dem Link zu den Dokumenten im obigen Kommentar von brutuscat folgen, werden Sie sehen, dass dies nicht der Fall ist. Dies ist das beabsichtigte Verhalten genau für diesen Fall.
– neu
4. August 2014 um 8:56 Uhr
-
Dies ist in der Tat die richtige Antwort. Obwohl die Abfrage etwas kontraintuitiv erscheint, ist dies genau das, was die MySQL-Dokumentation sagt.
– Timotheus Zorn
8. September 2014 um 0:21 Uhr
-
Falls die Abfrage Sie verwirrt, da LAST_INSERT_ID(expr) den Wert von expr für den UPDATE-Aufruf zurückgibt, können Sie es auch so verwenden:
UPDATE items SET qwe = 'qwe' WHERE asd = 'asd' AND LAST_INSERT_ID(item_id); SELECT LAST_INSERT_ID();
– Martinczerwi
29. April 2015 um 8:10 Uhr
Wladimir Kornea
Dies ist offiziell einfach, aber bemerkenswert kontraintuitiv. Wenn Sie tun:
update users set status="processing" where status="pending"
limit 1
Ändern Sie es so:
update users set status="processing" where status="pending"
and last_insert_id(user_id)
limit 1
Das Hinzufügen von last_insert_id(user_id)
in dem where
-Klausel weist MySQL an einstellen seine interne Variable auf die ID der gefundenen Zeile. Wenn Sie einen Wert an übergeben last_insert_id(expr)
Auf diese Weise wird am Ende dieser Wert zurückgegeben, der im Fall von IDs wie hier immer eine positive ganze Zahl ist und daher immer als wahr ausgewertet wird, ohne die where-Klausel zu beeinträchtigen. Dies funktioniert nur, wenn tatsächlich eine Zeile gefunden wurde. Denken Sie also daran, die betroffenen Zeilen zu überprüfen. Sie können die ID dann auf mehrere Arten erhalten.
Sie können Sequenzen generieren, ohne LAST_INSERT_ID() aufzurufen, aber der Nutzen der Verwendung der Funktion auf diese Weise besteht darin, dass der ID-Wert im Server als letzter automatisch generierter Wert beibehalten wird. Es ist für mehrere Benutzer sicher, da mehrere Clients die UPDATE-Anweisung absetzen und ihren eigenen Sequenzwert mit der SELECT-Anweisung (oder mysql_insert_id()) erhalten können, ohne andere Clients zu beeinflussen oder von ihnen beeinflusst zu werden, die ihre eigenen Sequenzwerte generieren.
Gibt den Wert zurück, der von der vorherigen INSERT- oder UPDATE-Anweisung für eine AUTO_INCREMENT-Spalte generiert wurde. Verwenden Sie diese Funktion, nachdem Sie eine INSERT-Anweisung in einer Tabelle ausgeführt haben, die ein AUTO_INCREMENT-Feld enthält, oder INSERT oder UPDATE verwendet haben, um einen Spaltenwert mit LAST_INSERT_ID(expr) festzulegen.
Der Grund für die Unterschiede zwischen LAST_INSERT_ID() und mysql_insert_id() ist, dass LAST_INSERT_ID() einfacher in Skripten verwendet werden kann, während mysql_insert_id() versucht, genauere Informationen darüber bereitzustellen, was mit der AUTO_INCREMENT-Spalte passiert.
Das Ausführen einer INSERT- oder UPDATE-Anweisung mit der Funktion LAST_INSERT_ID() ändert auch den von der Funktion mysqli_insert_id() zurückgegebenen Wert.
Alles zusammen:
$affected_rows = DB::getAffectedRows("
update users set status="processing"
where status="pending" and last_insert_id(user_id)
limit 1"
);
if ($affected_rows) {
$user_id = DB::getInsertId();
}
(FYI das Die DB-Klasse ist da.)
-
Wichtig zu beachten: Dies ist Multi-Connection-Safe, der dauerhafte Wert für last_insert_id oder mysql_insert_id (und vielleicht mysqli_insert_id, ich habe es nicht überprüft) gilt pro Verbindung. Fantastisch!
– Ryan S
9. Mai 2018 um 2:33 Uhr
-
Dies sieht nach einer guten Lösung aus, führte aber zu einem Fehler, den ich immer noch nicht verstehe – bei der Verarbeitung mehrerer Einträge wurde die Anzahl der zurückgegebenen IDs gelegentlich übersprungen, was ein anderes Verhalten als die ursprüngliche Abfrage ist, die eine abgeleitete Zusammenführung war (select-Anweisung Inside-Update-Anweisung). Ich musste dies rückgängig machen und stattdessen zwei verschiedene Abfragen durchführen.
– Lukas Bustamante
12. November 2021 um 21:36 Uhr
-
@LucasBustamante, was ist deine Umgebung? node-mysql2 Connection Pooling unterbricht Transaktionen, temporäre Tabellen und last_insert_id(). Die Problemumgehung besteht darin, eine Verbindung aus dem Pool zu extrahieren, aufeinanderfolgende Abfragen für dieselbe Verbindung auszuführen und die Verbindung dann wieder für den Pool freizugeben.
– Wladimir Kornea
12. November 2021 um 23:53 Uhr
Tschad von Nau
Dies ist dieselbe Methode wie die Antwort von Salman A, aber hier ist der Code, den Sie tatsächlich benötigen.
Bearbeiten Sie zunächst Ihre Tabelle so, dass sie automatisch verfolgt, wann immer eine Zeile geändert wird. Entfernen Sie die letzte Zeile, wenn Sie nur wissen möchten, wann eine Zeile ursprünglich eingefügt wurde.
ALTER TABLE mytable
ADD lastmodified TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Um dann die letzte aktualisierte Zeile herauszufinden, können Sie diesen Code verwenden.
SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;
Dieser Code ist alles aufgehoben MySQL vs. PostgreSQL: Hinzufügen einer Spalte „Zuletzt geändert“ zu einer Tabelle und MySQL-Handbuch: Zeilen sortieren. Ich habe es gerade zusammengebaut.
GigolNet Guigolachvili
Anfrage :
$sqlQuery = "UPDATE
update_table
SET
set_name="value"
WHERE
where_name="name"
LIMIT 1;";
PHP-Funktion:
function updateAndGetId($sqlQuery)
{
mysql_query(str_replace("SET", "SET id = LAST_INSERT_ID(id),", $sqlQuery));
return mysql_insert_id();
}
Das ist Arbeit für mich 😉
-
Ich mochte dasselbe, lief aber anders ref: forums.mysql.com/read.php?52,390616,390619
– Benutzer1642018
16. August 2015 um 14:40 Uhr
Gromisch
SET @uids := "";
UPDATE myf___ingtable
SET id = id
WHERE id < 5
AND ( SELECT @uids := CONCAT_WS(',', CAST(id AS CHAR CHARACTER SET utf8), @uids) );
SELECT @uids;
Ich musste die ID CAST (weiß nicht warum) … oder ich kann den Inhalt von @uids nicht abrufen (es war ein Blob). Übrigens vielen Dank für die Pomyk-Antwort!
-
Ich mochte dasselbe, lief aber anders ref: forums.mysql.com/read.php?52,390616,390619
– Benutzer1642018
16. August 2015 um 14:40 Uhr
olamundo
Hey, ich brauchte einfach so einen Trick – ich habe es anders gelöst, vielleicht funktioniert es bei dir. Beachten Sie, dass dies keine skalierbare Lösung ist und für große Datensätze sehr schlecht ist.
Teilen Sie Ihre Anfrage in zwei Teile auf –
Wählen Sie zuerst die IDs der Zeilen aus, die Sie aktualisieren möchten, und speichern Sie sie in einer temporären Tabelle.
Führen Sie zweitens die ursprüngliche Aktualisierung mit der Bedingung in der Aktualisierungsanweisung geändert zu durch where id in temp_table
.
Und um Parallelität zu gewährleisten, müssen Sie das tun sperren den Tisch vor diesen beiden Schritten und lösen Sie dann die Sperre am Ende.
Auch dies funktioniert bei mir für eine Abfrage, die mit endet limit 1
also verwende ich nicht einmal eine temporäre Tabelle, sondern einfach eine Variable, um das Ergebnis der ersten zu speichern select
.
Ich bevorzuge diese Methode, da ich weiß, dass ich immer nur eine Zeile aktualisieren werde und der Code unkompliziert ist.
mysqli_insert_id($link) gibt genau die ID der zuletzt aktualisierten Zeile zurück. Ich verwende diese Funktion in meinen Projekten für den gleichen Zweck. Sie können es sowohl in synchronen als auch in asynchronen Abfragen verwenden. Fügen Sie einfach $lastupdated_row_id = mysqli_insert_id($link) in Ihren Code ein und es wird für Sie funktionieren.
– Naeem Ul Wahhab
5. Februar 2013 um 6:23 Uhr
Kennen Sie die ID der Zeile nicht bereits, wenn Sie aktualisieren? Ich denke, es muss einige Fälle geben, in denen Sie dies nicht tun.
– jlcharette
27. Mai 2014 um 13:42 Uhr
Sie verwenden wahrscheinlich eine where-Klausel in Ihrer Update-Abfrage, warum können Sie nicht dieselbe where-Klausel in der select-Abfrage verwenden?
UPDATE foo WHERE bar = 1; SELECT id FROM foo WHERE bar = 1
?– Salmann A
7. August 2015 um 17:05 Uhr