Wie kann ich in PostgreSQL die letzte ID in eine Tabelle einfügen?
In MS SQL gibt es SCOPE_IDENTITY ().
Bitte raten Sie mir nicht, so etwas zu verwenden:
select max(id) from table
postgresql
insert
lastinsertid
Anton
quelle
quelle
Antworten:
(
tl;dr
: gehe zu Option 3: EINFÜGEN mit RÜCKGABE)Denken Sie daran, dass es in postgresql kein "id" -Konzept für Tabellen gibt, sondern nur Sequenzen (die normalerweise, aber nicht unbedingt als Standardwerte für Ersatzprimärschlüssel mit dem SERIAL- Pseudotyp verwendet werden).
Wenn Sie die ID einer neu eingefügten Zeile abrufen möchten, gibt es verschiedene Möglichkeiten:
Option 1 :
CURRVAL(<sequence name>);
.Zum Beispiel:
Der Name der Sequenz muss bekannt sein, er ist wirklich willkürlich; In diesem Beispiel wird davon ausgegangen, dass für die Tabelle
persons
eineid
Spalte mit demSERIAL
Pseudotyp erstellt wurde. Um sich nicht darauf zu verlassen und sich sauberer zu fühlen, können Sie stattdessen Folgendes verwendenpg_get_serial_sequence
:Vorsichtsmaßnahme: Funktioniert
currval()
nur nach einerINSERT
(ausgeführtennextval()
) Sitzung in derselben Sitzung .Option 2:
LASTVAL();
Dies ähnelt dem vorherigen, nur dass Sie den Sequenznamen nicht angeben müssen: Es wird nach der zuletzt geänderten Sequenz gesucht (immer innerhalb Ihrer Sitzung, dieselbe Einschränkung wie oben).
Beide
CURRVAL
undLASTVAL
sind absolut gleichzeitig sicher. Das Verhalten der Sequenz in PG ist so konzipiert, dass andere Sitzungen nicht stören, sodass kein Risiko für Rennbedingungen besteht (wenn eine andere Sitzung eine weitere Zeile zwischen meinem INSERT und meinem SELECT einfügt, erhalte ich immer noch meinen korrekten Wert).Sie haben jedoch ein subtiles potenzielles Problem. Wenn die Datenbank einen TRIGGER (oder eine REGEL) enthält, der beim Einfügen in eine
persons
Tabelle einige zusätzliche Einfügungen in andere Tabellen vornimmtLASTVAL
, erhalten wir wahrscheinlich den falschen Wert. Das Problem kann sogar auftretenCURRVAL
, wenn die zusätzlichen Einfügungen in dieselbepersons
Tabelle vorgenommen werden (dies ist viel weniger üblich, aber das Risiko besteht weiterhin).Option 3:
INSERT
mitRETURNING
Dies ist der sauberste, effizienteste und sicherste Weg, um die ID zu erhalten. Es hat keine der Risiken der vorherigen.
Nachteile? Fast keine: Möglicherweise müssen Sie die Art und Weise ändern, in der Sie Ihre INSERT-Anweisung aufrufen (im schlimmsten Fall erwartet Ihre API- oder DB-Schicht möglicherweise nicht, dass ein INSERT einen Wert zurückgibt). Es ist kein Standard-SQL (wen interessiert das?). es ist verfügbar seit Postgresql 8.2 (Dez 2006 ...)
Fazit: Wenn Sie können, wählen Sie Option 3. An anderer Stelle bevorzugen Sie 1.
Hinweis: Alle diese Methoden sind nutzlos, wenn Sie die zuletzt eingefügte ID global abrufen möchten (nicht unbedingt von Ihrer Sitzung). Dazu müssen Sie darauf zurückgreifen
SELECT max(id) FROM table
(dies liest natürlich keine nicht festgeschriebenen Einfügungen aus anderen Transaktionen).Umgekehrt sollten Sie nie benutzen ,
SELECT max(id) FROM table
anstatt eine der drei oben genannten Optionen, die ID nur von Euren zu bekommenINSERT
Aussage, weil sie (abgesehen von Leistung) nicht gleichzeitig sicher ist: zwischen IhrerINSERT
und IhrerSELECT
anderen Sitzung möglicherweise einem anderen Datensatz eingefügt haben.quelle
SELECT max(id)
erledigt den Job leider auch nicht, sobald Sie anfangen, Zeilen zu löschen.1,2,3,4,5
und die Zeilen 4 und 5 löschen, ist die zuletzt eingefügte ID immer noch 5, gibt abermax()
3 zurück.RETURNING id;
man dies in eine andere Tabelle einfügt, wäre willkommen!RETURNING id
ein SQL-Skript verwenden, das dempsql
Befehlszeilentool zugeführt wird ?Siehe die RETURNING-Klausel der INSERT- Anweisung. Grundsätzlich dient INSERT auch als Abfrage und gibt Ihnen den eingefügten Wert zurück.
quelle
insert into names (firstname, lastname) values ('john', 'smith') returning id;
, gibt es einfach id aus, als ob Sieselect id from names where id=$lastid
direkt ausgeführt hätten. Wenn Sie die Rückgabe in einer Variablen speichern möchten , istinsert into names (firstname, lastname) values ('john', 'smith') returning id into other_variable;
die Anweisung, die die Rückgabe enthält, die letzte Anweisung in einer Funktion , und die ID, die bearbeitet wirdreturning
, wird von der gesamten Funktion zurückgegeben.Sie können die RETURNING-Klausel in der INSERT-Anweisung wie folgt verwenden
quelle
Leonbloys Antwort ist ziemlich vollständig. Ich würde nur den Sonderfall hinzufügen, in dem der zuletzt eingefügte Wert aus einer PL / pgSQL-Funktion abgerufen werden muss, in der OPTION 3 nicht genau passt.
Zum Beispiel, wenn wir die folgenden Tabellen haben:
Wenn wir einen Kundendatensatz einfügen müssen, müssen wir uns auf einen Personendatensatz beziehen. Angenommen, wir möchten eine PL / pgSQL-Funktion entwickeln, die einen neuen Datensatz in den Client einfügt, sich aber auch um das Einfügen des neuen Personendatensatzes kümmert. Dafür müssen wir eine kleine Variation von Leonbloys OPTION 3 verwenden:
Beachten Sie, dass es zwei INTO-Klauseln gibt. Daher würde die PL / pgSQL-Funktion wie folgt definiert:
Jetzt können wir die neuen Daten einfügen mit:
oder
Und wir bekommen die neu erstellte ID.
quelle
Für diejenigen, die den gesamten Datensatz erhalten müssen, können Sie hinzufügen
bis zum Ende Ihrer Abfrage, um das Objekt all einschließlich der ID abzurufen.
quelle
Siehe das folgende Beispiel
Um die zuletzt eingefügte ID zu erhalten, verwenden Sie diese für die Tabelle "Benutzer".
quelle
Sie müssen natürlich den Tabellennamen und den Spaltennamen angeben.
Dies gilt für die aktuelle Sitzung / Verbindung http://www.postgresql.org/docs/8.3/static/functions-sequence.html
quelle
Versuche dies:
Wenn dies 1 zurückgibt (oder was auch immer der Startwert für Ihre Sequenz ist), setzen Sie die Sequenz auf den ursprünglichen Wert zurück und übergeben Sie das falsche Flag:
Andernfalls,
Dadurch wird der Sequenzwert auf den ursprünglichen Zustand zurückgesetzt und "setval" wird mit dem von Ihnen gesuchten Sequenzwert zurückgegeben.
quelle
Postgres verfügt über einen integrierten Mechanismus für denselben, der in derselben Abfrage die ID oder was auch immer Sie zurückgeben möchten, zurückgibt. Hier ist ein Beispiel. Angenommen, Sie haben eine Tabelle mit 2 Spalten Spalte1 und Spalte2 erstellt und möchten, dass Spalte1 nach jeder Einfügung zurückgegeben wird.
quelle
Ich hatte dieses Problem mit Java und Postgres. Ich habe es behoben, indem ich eine neue Connector-J-Version aktualisiert habe.
postgresql-9.2-1002.jdbc4.jar
https://jdbc.postgresql.org/download.html : Version 42.2.12
https://jdbc.postgresql.org/download/postgresql-42.2.12.jar
quelle