Möchten Sie die nächste ID oder die ID der Zeile, die Sie gerade einfügen? Das heißt, sollte die ID am Ende des Zahlungscodes die ID der Zeile sein, in der der Zahlungscode gespeichert ist?
Mike
ID der Zeile, die ich gerade
einfüge
6
Verketten Sie in diesem Fall die Werte, wenn Sie sie abrufen, nicht, wenn Sie sie einfügen. Auf diese Weise ist es viel einfacher, und Sie schließen aus, dass Sie die falsche ID erhalten oder ein Update ausführen müssen. Überlegen Sie, was passieren würde, wenn die gerade eingefügte Zeile von einem anderen Client angefordert wird, bevor das Update ausgeführt werden kann: dem Client würde mit einem ungültigen Zahlungscode enden. In einem verkehrsarmen System ist dies möglicherweise nicht der Fall, aber ich sehe keinen Grund, das Risiko einzugehen.
Sie können den nächsten Wert für die automatische Inkrementierung erhalten, indem Sie Folgendes tun:
SHOW TABLE STATUS FROM tablename LIKE Auto_increment
/*or*/SELECT`auto_increment`FROM INFORMATION_SCHEMA.TABLES
WHERE table_name ='tablename'
Beachten Sie, dass Sie dies nicht zum Ändern der Tabelle verwenden sollten. Verwenden Sie stattdessen eine Spalte auto_increment, um dies automatisch zu tun.
Das Problem ist, dass last_insert_id()es rückwirkend ist und somit innerhalb der aktuellen Verbindung garantiert werden kann.
Dieses Baby ist prospektiv und daher nicht pro Verbindung einzigartig und kann nicht als verlässlich angesehen werden.
Nur in einer einzigen Verbindungsdatenbank würde es funktionieren, aber einzelne Verbindungsdatenbanken haben heute die Angewohnheit, morgen mehrere Verbindungsdatenbanken zu werden.
Ich habe es nicht abgelehnt, aber das Problem beim Versuch, den letzten Wert für die automatische Inkrementierung zu verwenden, besteht darin, dass er möglicherweise nicht der letzte ist, wenn Sie ihn verwenden - unabhängig davon, wie schnell SELECT und das anschließende INSERT ausgeführt werden.
Mike
@ Mike, was ist, wenn es in einer einzelnen Abfrage durchgeführt wird? So etwas wie insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'? Ich würde die Aktualisierung im after insertTrigger verwenden und last_insert_id()obwohl ...
binaryLV
1
@binaryLV: Je kleiner der Abstand zwischen SELECT und INSERT ist, desto geringer ist die Wahrscheinlichkeit, dass sich der Wert geändert hat, dies schließt ihn jedoch nicht vollständig aus. Stellen Sie sich ein System mit Tausenden von Treffern pro Minute in der Datenbank vor - die Wahrscheinlichkeit, dass sich der Wert geändert hat, steigt dramatisch. Das Sperren von Tabellen oder Zeilen kann dies verhindern, wenn es als einzelne Abfrage ausgeführt wird. Dies hängt jedoch von einem bestimmten Verhalten des Datenbankmoduls ab, das möglicherweise nicht gut dokumentiert ist. Ich würde mit einem späteren gehen, UPDATEwenn ich auch hätte. Aber ich möchte die beiden lieber zur Anzeigezeit verketten und den ganzen Ärger sparen.
Mike
3
SHOW TABLE STATUSerwartet database namenach FROMund 'table name pattern'nach zu sehen LIKE.
X-Yuri
2
Da ein Cache zum Abrufen der Daten aus information_schema.tables verwendet wird, funktioniert diese Lösung für MySQL 8 nicht mehr.
Bruno
14
Dies gibt den automatischen Inkrementwert für die MySQL-Datenbank zurück und ich habe nicht mit anderen Datenbanken nachgefragt. Beachten Sie, dass bei Verwendung einer anderen Datenbank die Abfragesyntax möglicherweise anders ist.
SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name ='your_table_name'and table_schema ='your_database_name';SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name ='your_table_name'and table_schema =database();
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_name = 'your_table_name' und table_schema = 'your_database_name';
17.
10
Die Top-Antwort verwendet PHP MySQL_ für eine Lösung. Ich dachte, ich würde eine aktualisierte PHP MySQLi_- Lösung verwenden, um dies zu erreichen. In diesem Beispiel gibt es keine Fehlerausgabe!
$db = new mysqli('localhost','user','pass','database');$sql ="SHOW TABLE STATUS LIKE 'table'";$result=$db->query($sql);$row=$result->fetch_assoc();
echo $row['Auto_increment'];
Startet das nächste Auto-Inkrement, das in einer Tabelle angezeigt wird.
Denken Sie bei der ersten Methode daran, dass Sie, wenn der Datensatz mit der höchsten ID gelöscht wird, einen neuen Datensatz mit der ID erstellen, die die abgelegte ID früher hatte.
Tom Jenkinson
und wenn der vorherige Schlüssel in anderen Tabellen verwendet wurde und immer noch dort aufbewahrt wird, können Sie mit sehr seltsamer Magie enden
Tebe
Der erste gibt eine falsche ID zurück, wenn Sie den zuletzt eingefügten Datensatz
löschen.
6
Lösung:
CREATETRIGGER`IdTrigger` BEFORE INSERTON`payments`FOR EACH ROWBEGINSELECT AUTO_INCREMENT Into@xId
FROM information_schema.tables
WHERE
Table_SCHEMA ="DataBaseName"AND
table_name ="payments";SET NEW.`payment_code`= CONCAT("sahf4d2fdd45",@xId);END;
Das Aktualisieren payment_codeim after insertTrigger scheint die beste Option zu sein.
binaryLV
3
Sie können die ID beim Einfügen nicht verwenden und benötigen sie auch nicht. MySQL kennt die ID nicht einmal, wenn Sie diesen Datensatz einfügen. Sie können einfach "sahf4d2fdd45"in der payment_codeTabelle speichern idund payment_codespäter verwenden.
Wenn Sie Ihren Zahlungscode wirklich benötigen, um die ID zu enthalten, aktualisieren Sie die Zeile nach dem Einfügen, um die ID hinzuzufügen.
+1 Um dies etwas deutlicher zu machen: Wenn Sie den 'neuesten' Wert aus einer Spalte abrufen, wird garantiert, dass er genau zum Zeitpunkt des Abrufs der neueste Wert ist. Es ist möglicherweise nicht der neueste Wert, wenn Sie diesen Wert in einer nachfolgenden Einfügung verwenden. Bei einer Spalte mit automatischer Inkrementierung besteht immer die Möglichkeit, dass zwischen dem Zeitpunkt, zu dem Sie die ID abgerufen haben, und dem Zeitpunkt, zu dem Sie sie an einer anderen Stelle einfügen, ein weiterer Wert hinzugefügt wurde. Wenn Sie auf eine gerade eingefügte Zeile verweisen, ist die Verwendung von LAST_INSERT_ID () in Ordnung. Wenn Sie versuchen, einen eindeutigen Wert sicherzustellen, ist dies nicht der Fall.
Mike
@cularis, MySQL kennt die nächste Auto_Increment-ID, die in der information_schema.tablesTabelle aufgeführt ist.
Johan
1
@faressoft: Wenn Sie einen Zahlungscode haben möchten, der eine eindeutige Zeichenfolge sowie die ID der Zeile enthält, die diesen Zahlungscode enthält, kombinieren Sie die beiden beim Abrufen der Zeile - entweder mit einem SELECT ... CONCAT(payment_code, id)oder in Ihrem Anwendungscode. Sie können das sogar SELECTin ein VIEWeinpacken, sodass Sie immer den richtigen Wert zurückgeben, ohne sich bei jedem SELECT Ihrer App um das CONCAT kümmern zu müssen.
Mike
3
Wofür benötigen Sie die nächste inkrementelle ID?
MySQL erlaubt nur ein Auto-Inkrement-Feld pro Tabelle und muss auch der Primärschlüssel sein, um die Eindeutigkeit zu gewährleisten.
Beachten Sie, dass die nächste Einfügungs-ID bei Verwendung möglicherweise nicht verfügbar ist, wenn Sie sie verwenden, da der Wert, den Sie haben, nur im Rahmen dieser Transaktion liegt. Abhängig von der Auslastung Ihrer Datenbank wird dieser Wert möglicherweise bereits zum Zeitpunkt der nächsten Anforderung verwendet.
Ich würde vorschlagen, dass Sie Ihr Design überprüfen, um sicherzustellen, dass Sie nicht wissen müssen, welcher Wert für die automatische Inkrementierung als Nächstes zugewiesen werden soll
Es ist keine gute Idee, die Art der Anwendung anzunehmen, für die die ID erforderlich ist. Es gibt Anwendungen wie die, an der ich gerade arbeite, die die nächste inkrementelle ID benötigen, und der abgerufene Wert ist nicht gefährdet, einem anderen Skript zugewiesen zu werden.
JG Estiot
3
Ich schlage vor, zu überdenken, was Sie tun. Ich habe noch nie einen einzigen Anwendungsfall erlebt, in dem dieses spezielle Wissen erforderlich ist. Die nächste ID ist ein ganz besonderes Implementierungsdetail, und ich würde nicht damit rechnen, dass sie ACID-sicher ist.
Führen Sie eine einfache Transaktion durch, bei der Ihre eingefügte Zeile mit der letzten ID aktualisiert wird:
BEGIN;INSERTINTO payments (date, item, method)VALUES(NOW(),'1 Month','paypal');UPDATE payments SET payment_code = CONCAT("sahf4d2fdd45", LAST_INSERT_ID())WHERE id = LAST_INSERT_ID();COMMIT;
Ich kann einen solchen Anwendungsfall nennen, ich versuche ein Produktionsproblem zu diagnostizieren, also muss ich herausfinden, ob die letzte Zeile in einer Tabelle wirklich die letzte Zeile ist oder ob nach der einen Zeile hinzugefügt wurde, die irgendwie gelöscht wurde, Tabelle enthält ein auto_increment-Feld. Wenn ich diese Informationen finde, kann ich schließen, ob die Zeile gelöscht oder nie hinzugefügt wurde.
Usman
1
Das könnte vielleicht für Sie funktionieren, aber ich würde mich nicht darauf verlassen, da ich glaube, dass Sie keine Garantie dafür haben: dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html " Wenn die Spalte AUTO_INCREMENT Teil eines mehrspaltigen Index ist, werden die Werte für AUTO_INCREMENT wiederverwendet, wenn Sie die Zeile mit dem größten Wert für AUTO_INCREMENT in einer Gruppe löschen. "
Markus Malkusch
Vielen Dank, nützliche Informationen, auch gemäß Ihrem freigegebenen Link kann auto_increment zurückgesetzt werden, indem manuell eine Nummer eingefügt wird, also ja nicht zuverlässig.
Usman
2
Sie müssen eine Verbindung zu MySQL herstellen und eine Datenbank auswählen, bevor Sie dies tun können
$table_name ="myTable";$query = mysql_query("SHOW TABLE STATUS WHERE name='$table_name'");$row= mysql_fetch_array($query);$next_inc_value =$row["AUTO_INCREMENT"];
benutze "mysql_insert_id ()". mysql_insert_id () wirkt auf die zuletzt ausgeführte Abfrage. Rufen Sie mysql_insert_id () unmittelbar nach der Abfrage auf, die den Wert generiert.
Nachfolgend finden Sie ein Anwendungsbeispiel:
<?php
$link = mysql_connect('localhost','username','password');if(!$link){
die('Could not connect: '. mysql_error());}
mysql_select_db('mydb');
mysql_query("INSERT INTO mytable VALUES('','value')");
printf("Last inserted record has id %d\n", mysql_insert_id());?>
Ich stimme auch zu, dass dies der einfachste Ansatz ist. Ich bin mir nicht sicher, warum Sie herabgestimmt wurden, aber ich werde mit einer Gegenstimme ausgleichen.
Rekurs
Ich habe die Notwendigkeit einer Transaktion nicht erwähnt. Wenn Sie sie nicht in eine Transaktion einbinden, ist dieser Code so schnell wie möglich mies, da er dem tatsächlichen Laden entspricht.
Tebe
1
Was ist, wenn die letzte Zeile gelöscht wurde? Oder wurden mehrere letzte Zeilen gelöscht?
Liam W
Freigegebene Schlüssel ohne Probleme werden nur verwendet, wenn Sie sie explizit angeben
Tebe
1
mit der Antwort von ravi404:
CREATEFUNCTION`getAutoincrementalNextVal`(`TableName` VARCHAR(50))
RETURNS BIGINT
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''BEGINDECLARE Value BIGINT;SELECT
AUTO_INCREMENT INTO Value
FROM
information_schema.tables
WHERE
table_name = TableName AND
table_schema =DATABASE();RETURN Value;END
Verwenden Sie in Ihrer Einfügeabfrage, um einen SHA1-Hash zu erstellen. Ex.:
Funktioniert das immer Gibt es Rennbedingungen, wenn zwei Einsätze gleichzeitig erfolgen?
Jmons
0
Verbesserung von @ ravi404, falls Ihr Autoincrement-Offset NICHT 1 ist:
SELECT(`auto_increment`-1)+ IFNULL(@@auto_increment_offset,1)FROM INFORMATION_SCHEMA.TABLES
WHERE table_name = your_table_name
AND table_schema =DATABASE();
( auto_increment-1): Die DB-Engine scheint immer einen Offset von 1 zu berücksichtigen. Sie müssen diese Annahme also verwerfen und dann den optionalen Wert von @@ auto_increment_offset oder standardmäßig 1: IFNULL (@@ auto_increment_offset, 1) hinzufügen.
$auto_inc_db = mysql_query("SELECT * FROM my_table_name ORDER BY id ASC ");while($auto_inc_result = mysql_fetch_array($auto_inc_db)){$last_id =$auto_inc_result['id'];}$next_id =($last_id+1);
echo $next_id;//this is the new id,if auto increment ison
auto_increment
SäuleAntworten:
Verwendung
LAST_INSERT_ID()
aus Ihrer SQL-Abfrage.Oder
Sie können es auch verwenden
mysql_insert_id()
, um es mit PHP zu bekommen.quelle
LAST_INSERT_ID()
.mysqli_insert_id
Sie können verwenden
oder wenn Sie information_schema nicht verwenden möchten, können Sie dies verwenden
quelle
TABLES.AUTO_INCREMENT
wird zwischengespeichert dev.mysql.com/doc/refman/8.0/en/… . MySQL-Blog hat auch mehrere Beiträge darüber, aber die Systemvariable, die sie erwähnen, scheint veraltet zu sein: mysqlserverteam.com/… mysqlserverteam.com/…Sie können den nächsten Wert für die automatische Inkrementierung erhalten, indem Sie Folgendes tun:
Beachten Sie, dass Sie dies nicht zum Ändern der Tabelle verwenden sollten. Verwenden Sie stattdessen eine Spalte auto_increment, um dies automatisch zu tun.
Das Problem ist, dass
last_insert_id()
es rückwirkend ist und somit innerhalb der aktuellen Verbindung garantiert werden kann.Dieses Baby ist prospektiv und daher nicht pro Verbindung einzigartig und kann nicht als verlässlich angesehen werden.
Nur in einer einzigen Verbindungsdatenbank würde es funktionieren, aber einzelne Verbindungsdatenbanken haben heute die Angewohnheit, morgen mehrere Verbindungsdatenbanken zu werden.
Sehen:
SHOW TABLE STATUS
quelle
insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'
? Ich würde die Aktualisierung imafter insert
Trigger verwenden undlast_insert_id()
obwohl ...UPDATE
wenn ich auch hätte. Aber ich möchte die beiden lieber zur Anzeigezeit verketten und den ganzen Ärger sparen.SHOW TABLE STATUS
erwartetdatabase name
nachFROM
und'table name pattern'
nach zu sehenLIKE
.Dies gibt den automatischen Inkrementwert für die MySQL-Datenbank zurück und ich habe nicht mit anderen Datenbanken nachgefragt. Beachten Sie, dass bei Verwendung einer anderen Datenbank die Abfragesyntax möglicherweise anders ist.
quelle
Die Top-Antwort verwendet PHP MySQL_ für eine Lösung. Ich dachte, ich würde eine aktualisierte PHP MySQLi_- Lösung verwenden, um dies zu erreichen. In diesem Beispiel gibt es keine Fehlerausgabe!
Startet das nächste Auto-Inkrement, das in einer Tabelle angezeigt wird.
quelle
In PHP können Sie dies versuchen:
ODER
quelle
Lösung:
"DataBaseName" ist der Name unserer Datenbank
quelle
Eine einfache Abfrage würde genügen
SHOW TABLE STATUS LIKE 'table_name'
quelle
Sie können den MySQL-Trigger verwenden
quelle
payment_code
imafter insert
Trigger scheint die beste Option zu sein.Sie können die ID beim Einfügen nicht verwenden und benötigen sie auch nicht. MySQL kennt die ID nicht einmal, wenn Sie diesen Datensatz einfügen. Sie können einfach
"sahf4d2fdd45"
in derpayment_code
Tabelle speichernid
undpayment_code
später verwenden.Wenn Sie Ihren Zahlungscode wirklich benötigen, um die ID zu enthalten, aktualisieren Sie die Zeile nach dem Einfügen, um die ID hinzuzufügen.
quelle
information_schema.tables
Tabelle aufgeführt ist.SELECT ... CONCAT(payment_code, id)
oder in Ihrem Anwendungscode. Sie können das sogarSELECT
in einVIEW
einpacken, sodass Sie immer den richtigen Wert zurückgeben, ohne sich bei jedem SELECT Ihrer App um das CONCAT kümmern zu müssen.Wofür benötigen Sie die nächste inkrementelle ID?
MySQL erlaubt nur ein Auto-Inkrement-Feld pro Tabelle und muss auch der Primärschlüssel sein, um die Eindeutigkeit zu gewährleisten.
Beachten Sie, dass die nächste Einfügungs-ID bei Verwendung möglicherweise nicht verfügbar ist, wenn Sie sie verwenden, da der Wert, den Sie haben, nur im Rahmen dieser Transaktion liegt. Abhängig von der Auslastung Ihrer Datenbank wird dieser Wert möglicherweise bereits zum Zeitpunkt der nächsten Anforderung verwendet.
Ich würde vorschlagen, dass Sie Ihr Design überprüfen, um sicherzustellen, dass Sie nicht wissen müssen, welcher Wert für die automatische Inkrementierung als Nächstes zugewiesen werden soll
quelle
Ich schlage vor, zu überdenken, was Sie tun. Ich habe noch nie einen einzigen Anwendungsfall erlebt, in dem dieses spezielle Wissen erforderlich ist. Die nächste ID ist ein ganz besonderes Implementierungsdetail, und ich würde nicht damit rechnen, dass sie ACID-sicher ist.
Führen Sie eine einfache Transaktion durch, bei der Ihre eingefügte Zeile mit der letzten ID aktualisiert wird:
quelle
Sie müssen eine Verbindung zu MySQL herstellen und eine Datenbank auswählen, bevor Sie dies tun können
quelle
benutze "mysql_insert_id ()". mysql_insert_id () wirkt auf die zuletzt ausgeführte Abfrage. Rufen Sie mysql_insert_id () unmittelbar nach der Abfrage auf, die den Wert generiert.
Nachfolgend finden Sie ein Anwendungsbeispiel:
Ich hoffe, dass das obige Beispiel nützlich ist.
quelle
Das ist es :)
quelle
Ich bezweifle zwar an seiner Produktivität, aber es ist 100% zuverlässig
quelle
mit der Antwort von ravi404:
Verwenden Sie in Ihrer Einfügeabfrage, um einen SHA1-Hash zu erstellen. Ex.:
quelle
Verbesserung von @ ravi404, falls Ihr Autoincrement-Offset NICHT 1 ist:
(
auto_increment
-1): Die DB-Engine scheint immer einen Offset von 1 zu berücksichtigen. Sie müssen diese Annahme also verwerfen und dann den optionalen Wert von @@ auto_increment_offset oder standardmäßig 1: IFNULL (@@ auto_increment_offset, 1) hinzufügen.quelle
Bei mir funktioniert es und sieht einfach aus:
quelle
$last_id
wiederholt zuzuweisen, wenn Sie nur könnenDESC
. Ihrwhile
Block hat eine Menge nutzloser Arbeit geleistet.Wenn Sie kein korrektes AUTO_INCREMENT zurückgeben, versuchen Sie es:
Dieser leere Cache für die Tabelle in BD
quelle