Ich habe einen Tisch:
CREATE TABLE names (id serial, name varchar(20))
Ich möchte die "zuletzt eingefügte ID" aus dieser Tabelle, ohne RETURNING id
beim Einfügen zu verwenden. Es scheint eine Funktion zu geben CURRVAL()
, aber ich verstehe nicht, wie man sie benutzt.
Ich habe versucht mit:
SELECT CURRVAL() AS id FROM names_id_seq
SELECT CURRVAL('names_id_seq')
SELECT CURRVAL('names_id_seq'::regclass)
aber keiner von ihnen funktioniert. Wie kann ich currval()
die zuletzt eingegebene ID ermitteln?
postgresql
sequence
Jonas
quelle
quelle
currval()
wird auf keinen Fall entmutigt.Antworten:
Wenn Sie eine Spalte als
serial
PostgreSQL erstellen, wird automatisch eine Sequenz dafür erstellt.Der Name der Sequenz wird automatisch generiert und lautet immer tablename_columnname_seq. In Ihrem Fall handelt es sich bei der Sequenz um Namen
names_id_seq
.Nach dem Einfügen in die Tabelle können Sie
currval()
mit diesem Sequenznamen aufrufen :Anstatt den Sequenznamen fest zu codieren, können Sie auch Folgendes verwenden
pg_get_serial_sequence()
:Auf diese Weise müssen Sie sich nicht auf die von Postgres verwendete Namensstrategie verlassen.
Oder wenn Sie den Sequenznamen überhaupt nicht verwenden möchten, verwenden Sie
lastval()
quelle
currval()
in einem Mehrbenutzer-Setup zu verwenden. ZB auf einem Webserver.currval()
ist "lokal" für Ihre aktuelle Verbindung. Daher ist die Verwendung in einer Mehrbenutzerumgebung kein Problem. Das ist der ganze Zweck einer Sequenz.Dies geht direkt vom Stapelüberlauf aus
Wie von @a_horse_with_no_name und @Jack Douglas hervorgehoben, funktioniert currval nur mit der aktuellen Sitzung. Wenn Sie also damit einverstanden sind, dass das Ergebnis durch eine nicht festgeschriebene Transaktion einer anderen Sitzung beeinflusst wird, und Sie dennoch etwas möchten, das über mehrere Sitzungen hinweg funktioniert, können Sie Folgendes verwenden:
Verwenden Sie den Link zu SO für weitere Informationen.
Aus der Dokumentation von Postgres geht jedoch eindeutig hervor, dass
Eigentlich müssten Sie also so etwas tun, um currval oder last_value für eine sitzungsübergreifende Sequenz richtig zu verwenden?
Vorausgesetzt natürlich, Sie haben in der aktuellen Sitzung keine Einfügung oder andere Möglichkeit, das serielle Feld zu verwenden.
quelle
nextval()
Sie die Reihenfolge manuell so einstellen, dass sie mit der Anzahl der Fixture Records übereinstimmt, die Sie mit den fest codierten IDs eingefügt haben. Um das Problem zu lösen, dass currval () / lastval () nicht vor nextval verfügbar ist, müssen SieSELECT
die Sequenz direkt eingeben .Sie müssen
nextval
diese Sequenz in dieser Sitzung aufrufen, bevor Siecurrval
:Daher können Sie die 'zuletzt eingefügte ID' in der Sequenz nicht finden, es sei denn,
insert
dies erfolgt in derselben Sitzung (eine Transaktion wird möglicherweise zurückgesetzt, die Sequenz jedoch nicht).Wie in der Antwort von a_horse ausgeführt, wird
create table
mit einer Spalte vom Typserial
automatisch eine Sequenz erstellt und verwendet, um den Standardwert für die Spalte zu generieren, sodassinsert
normalerweisenextval
implizit auf Folgendes zugegriffen wird :quelle
Es gibt also einige Probleme mit diesen verschiedenen Methoden:
Currval ruft nur den letzten in der aktuellen Sitzung generierten Wert ab. Dies ist hilfreich, wenn Sie keine anderen Werte generieren, aber in Fällen, in denen Sie möglicherweise einen Trigger aufrufen und / oder die Sequenz in der aktuellen Transaktion mehrmals vorverlegt haben, ist dies der Fall Es wird nicht der richtige Wert zurückgegeben. Das ist kein Problem für 99% der Leute da draußen - aber es ist etwas, das man berücksichtigen sollte.
Der beste Weg, den eindeutigen Bezeichner nach einer Einfügeoperation zu erhalten, ist die Verwendung der RETURNING-Klausel. Im folgenden Beispiel wird davon ausgegangen, dass die an die Sequenz gebundene Spalte "id" heißt:
Beachten Sie, dass die Nützlichkeit der RETURNING-Klausel weit über das Abrufen der Sequenz hinausgeht, da sie auch Folgendes bewirkt:
Liefert die gelöschten Werte:
aus Tabelle A löschen, wobei ID> 100 zurückgibt *
Gibt die geänderten Zeilen nach einem UPDATE zurück:
Tabelle aktualisieren A setze X = 'y' wobei blah = 'blech' zurückkehrt *
Verwenden Sie das Ergebnis eines Löschvorgangs für ein Update:
WITH A as (lösche * aus Tabelle A als Rückgabe-ID) Update B set deleted = true wobei ID in (wähle ID aus A);
quelle
RETURNING
Klausel verwenden wollten - aber es ist nichts Falsches daran, die Vorteile der Verwendung für andere klarer zu machen.Ich musste eine Abfrage ausführen, obwohl ich SQLALchemy verwendet habe, da ich currval nicht erfolgreich eingesetzt habe.
Dies war ein Python-Kolben + Postgresql-Projekt.
quelle
Wenn Sie den Wert der Sequenzen erhalten möchten, ohne aufgerufen zu
nextval()
haben und ohne die Sequenz zu ändern, habe ich eine PL / pgSQL-Funktion zusammengestellt, um damit umzugehen : Ermitteln Sie den Wert aller Datenbanksequenzenquelle
Sie müssen das
GRANT
Schema folgendermaßen verwenden:und
quelle
currval()
Funktion aufrufen , um sie für diesen Thread relevanter zu machen?In PostgreSQL 11.2 können Sie die Sequenz wie eine Tabelle behandeln:
Beispiel, wenn Sie eine Sequenz mit dem Namen "names_id_seq" haben
Das sollte Ihnen die letzte eingegebene ID geben (in diesem Fall 4), was bedeutet, dass der aktuelle Wert (oder der Wert, der für die nächste ID verwendet werden soll) 5 sein sollte.
quelle
Verschiedene Versionen von PostgreSQL verfügen möglicherweise über verschiedene Funktionen, um die aktuelle oder nächste Sequenz-ID abzurufen.
Zunächst müssen Sie die Version Ihres Postgres kennen. Verwenden der ausgewählten Version (); um die version zu bekommen.
In PostgreSQL 8.2.15 erhalten Sie die aktuelle Sequenz-ID mit
select last_value from schemaName.sequence_name
.Wenn die obige Anweisung nicht funktioniert, können Sie verwenden
select currval('schemaName.sequence_name');
quelle