Ich habe eine kleine Tabelle (~ 30 Zeilen) in meiner Postgres 9.0-Datenbank mit einem Ganzzahl-ID-Feld (dem Primärschlüssel), das derzeit eindeutige aufeinanderfolgende Ganzzahlen ab 1 enthält, die jedoch nicht mit dem Schlüsselwort 'serial' erstellt wurden.
Wie kann ich diese Tabelle so ändern, dass Einfügungen in diese Tabelle von nun an dazu führen, dass sich dieses Feld so verhält, als ob es mit dem Typ 'serial' erstellt worden wäre?
postgresql
nicolaskruchten
quelle
quelle
SERIAL
Pseudotyp ist jetzt ein Legacy -Typ , der durch die neueGENERATED … AS IDENTITY
Funktion ersetzt wird, die in SQL: 2003 , in Postgres 10 und höher definiert ist. Siehe Erklärung .Antworten:
Sehen Sie sich die folgenden Befehle an (insbesondere den kommentierten Block).
quelle
ALTER TABLE foo ADD PRIMARY KEY (a)
.ALTER TABLE foo OWNER TO current_user;
zuerst tun .MAX(a)+1
auf setval setzen?SELECT MAX(a)+1 FROM foo; SELECT setval('foo_a_seq', 6);
Sie können auch
START WITH
eine Sequenz von einem bestimmten Punkt aus starten, obwohl setval dasselbe bewirkt wie in Eulers Antwort, z.quelle
TL; DR
Hier ist eine Version, in der Sie keinen Menschen benötigen, um einen Wert zu lesen und selbst einzugeben.
Eine andere Möglichkeit wäre, das
Function
am Ende dieser Antwort freigegebene wiederverwendbare zu verwenden .Eine nicht interaktive Lösung
Fügen Sie einfach die beiden anderen Antworten hinzu, für diejenigen von uns, die diese
Sequence
von einem nicht interaktiven Skript erstellen lassen müssen, während sie beispielsweise eine Live-Datenbank patchen.Das heißt, wenn Sie
SELECT
den Wert nicht manuell eingeben und selbst in eine nachfolgendeCREATE
Anweisung eingeben möchten.Kurz gesagt, Sie können nicht tun:
... da die
START [WITH]
Klausel inCREATE SEQUENCE
einen Wert erwartet , keine Unterabfrage.Tut es
setval()
jedoch! Somit ist folgendes absolut in Ordnung:Wenn keine Daten vorhanden sind und Sie nichts darüber wissen (möchten),
coalesce()
legen Sie den Standardwert fest:Das Einstellen des aktuellen Sequenzwerts
0
ist jedoch umständlich, wenn nicht sogar unzulässig.Die Verwendung der Drei-Parameter-Form von
setval
wäre angemessener:Durch Einstellen des optionalen dritten Parameters von
setval
tofalse
wird verhindert, dass der nächstenextval
die Sequenz vor dem Zurückgeben eines Werts vorverlegt, und somit:- Aus diesem Eintrag in der Dokumentation
In einem nicht verwandten Hinweis können Sie auch die Spalte angeben, die die
Sequence
direkt mitCREATE
besitzt. Sie müssen sie später nicht mehr ändern:Zusammenfassend:
Verwendung einer
Function
Wenn Sie dies für mehrere Spalten planen, können Sie alternativ eine tatsächliche verwenden
Function
.Verwenden Sie es so:
quelle
coalesce(max(a), 0))
daran, dass dies die meiste Zeit nicht funktioniert, da die IDs normalerweise bei 1 beginnen. Richtiger wärecoalesce(max(a), 1))
setval
Funktion setzt eigentlich nur den aktuell "zuletzt verwendeten Wert" für die Sequenz. Der nächste verfügbare Wert (der erste, der tatsächlich verwendet wird) ist ein weiterer! Wenn Siesetval(..., coalesce(max(a), 1))
eine leere Spalte verwenden, wird sie so eingestellt, dass sie mit2
(dem nächsten verfügbaren Wert) beginnt , wie in der Dokumentation dargestellt .currval
sollte niemals sein0
, auch wenn es sich nicht im tatsächlichen Datensatz widerspiegelt. Die Verwendung der Drei-Parameter-Form vonsetval
wäre angemessener :setval(..., coalesce(max(a), 0) + 1, false)
. Antwort entsprechend aktualisiert!