wake-up-neo.com

Wie bekomme ich die ID der letzten aktualisierten Zeile in MySQL?

Wie erhalte ich die ID der letzten aktualisierten Zeile in MySQL mit PHP?

118
Avinash

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;

EDITvon aefxx

Diese Technik kann weiter erweitert werden, um die ID jeder Zeile abzurufen, die von einer Aktualisierungsanweisung betroffen ist:

SET @uids := null;
UPDATE footable
   SET foo = 'bar'
 WHERE fooid > 5
   AND ( SELECT @uids := CONCAT_WS(',', fooid, @uids) );
SELECT @uids;

Dadurch wird eine Zeichenfolge mit allen durch ein Komma verketteten IDs zurückgegeben.

215
Pomyk

Hm, ich bin überrascht, dass ich unter den Antworten nicht die einfachste Lösung sehe.

Angenommen, 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 die letzte betroffene Zeile direkt nach der Anweisung zu erfahren, sollten Sie die Anweisung anschließend folgendermaßen aktualisieren:

UPDATE items
SET qwe = 'qwe',
    item_id=LAST_INSERT_ID(item_id)
WHERE asd = 'asd';
SELECT LAST_INSERT_ID();

Wenn Sie nur die wirklich geänderte Zeile aktualisieren müssen, müssen Sie über die LAST_INSERT_ID eine bedingte Aktualisierung der item_id hinzufügen, um zu prüfen, ob sich die Daten in der Zeile ändern.

30
newtover

Dies ist die gleiche 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 bei jeder Änderung einer Zeile automatisch den Überblick behält. 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 die letzte aktualisierte Zeile herauszufinden, können Sie diesen Code verwenden.

SELECT id FROM mytable ORDER BY lastmodified DESC LIMIT 1;

Dieser Code wird aus MySQL vs PostgreSQL entfernt: Hinzufügen einer Spalte 'Zuletzt geändert' zu einer Tabelle und MySQL-Benutzerhandbuch: Sortieren von Zeilen Ich habe es gerade zusammengebaut.

10
Chad von Nau

Dies ist offiziell einfach, aber erstaunlich kontraintuitiv. Wenn du tust:

update users set status = 'processing' where status = 'pending' limit 1

Ändern Sie es zu diesem:

update users set status = 'processing' where status = 'pending' and last_insert_id(user_id) limit 1

Der Zusatz von last_insert_id(user_id) in der where-Klausel teilt MySQL mit set seiner internen Variablen die ID der gefundenen Zeile mit. Wenn Sie einen solchen Wert an last_insert_id(expr) übergeben, gibt er diesen Wert zurück, der bei IDs wie hier immer eine positive ganze Zahl ist und daher immer als true ausgewertet wird, ohne die where-Klausel zu beeinträchtigen. Dies funktioniert nur, wenn tatsächlich eine Zeile gefunden wurde. Überprüfen Sie daher die betroffenen Zeilen. Sie können die ID dann auf verschiedene Arten erhalten.

MySQL last_insert_id()

Sie können Sequenzen generieren, ohne LAST_INSERT_ID () aufzurufen, jedoch die Die Funktion kann auf diese Weise verwendet werden, wenn der ID-Wert .__ ist. wird als letzter automatisch generierter Wert auf dem Server gespeichert. Es ist sicher für mehrere Benutzer, da mehrere Clients UPDATE .__ ausgeben können. Anweisung und erhalten ihren eigenen Sequenzwert mit der SELECT-Anweisung (oder mysql_insert_id ()), ohne Auswirkungen auf andere Clients, die ihre eigenen Sequenzwerte generieren.

MySQL mysql_insert_id()

Gibt den Wert zurück, der für eine AUTO_INCREMENT-Spalte von .__ generiert wurde. vorherige INSERT- oder UPDATE-Anweisung. Verwenden Sie diese Funktion, nachdem Sie führte eine INSERT-Anweisung in eine Tabelle ein, die ein .__ enthält. AUTO_INCREMENT-Feld oder haben mit INSERT oder UPDATE eine Spalte festgelegt Wert mit LAST_INSERT_ID (Ausdruck).

Der Grund für die Unterschiede zwischen LAST_INSERT_ID () und mysql_insert_id () besagt, dass LAST_INSERT_ID () in .__ einfach zu verwenden ist. Skripts, während mysql_insert_id () versucht, genauer anzugeben Informationen darüber, was mit der Spalte AUTO_INCREMENT geschieht.

PHP mysqli_insert_id()

Ausführen einer INSERT- oder UPDATE-Anweisung unter Verwendung der LAST_INSERT_ID () Die Funktion ändert auch den von mysqli_insert_id () .__ zurückgegebenen Wert. Funktion.

Alles zusammenstellen:

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

(Zu Ihrer Information, dass DB-Klasse hier ist .)

9
Vladimir Kornea

Abfrage:

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

Es ist Arbeit für mich;)

Die ID der letzten aktualisierten Zeile ist dieselbe ID, die Sie in der 'updateQuery' verwendet haben, um diese Zeile zu finden und zu aktualisieren. Speichern Sie also einfach diese ID auf, wo immer Sie möchten.

last_insert_id() hängt vom AUTO_INCREMENT ab, die letzte aktualisierte ID jedoch nicht. 

2
Driada

Weiter zur oben akzeptierten Antwort
Für diejenigen, die sich über := & = wundern

Signifikanter Unterschied zwischen := und =, und das heißt, := arbeitet überall als Variablenzuweisungsoperator, während = in SET-Anweisungen nur auf diese Weise funktioniert und überall ein Vergleichsoperator ist. 

SELECT @var = 1 + 1; lässt @var unverändert und gibt boolean zurück (1 oder 0, abhängig vom aktuellen Wert von @var), während SELECT @var := 1 + 1;@var in 2 und return 2 . ändert. [Quelle]

2
Anon30

Hey, ich brauchte nur einen solchen Trick - ich habe es auf eine andere Art gelöst, vielleicht klappt es bei Ihnen. 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 zunächst die IDs der Zeilen aus, die Sie aktualisieren möchten, und speichern Sie sie in einer temporären Tabelle. 

führen Sie anschließend die ursprüngliche Aktualisierung durch, wobei die Bedingung in der Aktualisierungsanweisung in where id in temp_table geändert wurde.

Um die Parallelität zu gewährleisten, müssen Sie die Tabelle vor diesen beiden Schritten mit lock sperren und am Ende die Sperre aufheben.

Auch dies funktioniert für mich, für eine Abfrage, die mit limit 1 endet, daher verwende ich nicht einmal eine temporäre Tabelle, sondern lediglich eine Variable, um das Ergebnis der ersten select zu speichern. 

Ich bevorzuge diese Methode, da ich weiß, dass ich immer nur eine Zeile aktualisieren werde und der Code unkompliziert ist. 

2
olamundo
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 bekommen (es war ein Fleck).

1
Gromish

Wenn Sie nur Einfügungen vornehmen und eine aus derselben Sitzung machen möchten, tun Sie dies wie in der Antwort von peirix. Wenn Sie Änderungen vornehmen, müssen Sie Ihr Datenbankschema ändern, um zu speichern, welcher Eintrag zuletzt aktualisiert wurde.

Wenn Sie möchten, dass die ID von der letzten Änderung stammt, die möglicherweise von einer anderen Sitzung stammt (dh nicht die, die gerade vom PHP -Code ausgeführt wurde, sondern als Antwort auf eine andere Anforderung), Sie können Ihrer Tabelle eine TIMESTAMP-Spalte mit dem Namen last_modified hinzufügen (Informationen hierzu finden Sie unter http://dev.mysql.com/doc/refman/5.1/en/datetime.html ). Bei der Aktualisierung setzen Sie last_modified = CURRENT_TIME.

Wenn Sie dies festgelegt haben, können Sie eine Abfrage wie folgt verwenden: SELECT id FROM-Tabelle ORDER BY last_modified DESC LIMIT 1; , Um die zuletzt geänderte Zeile abzurufen.

1
a1kmm

Meine Lösung ist, zuerst die "id" (@uids) mit select-Befehl zu wählen und diese ID mit @uids zu aktualisieren.

SET @uids := (SELECT id FROM table WHERE some = 0 LIMIT 1);
UPDATE table SET col = 1 WHERE id = @uids;SELECT @uids;

es hat an meinem Projekt gearbeitet.

0
Ahmet Uğur