Postgres ändern die Reihenfolge manuell


189

Ich versuche, eine Sequenz auf einen bestimmten Wert festzulegen.

SELECT setval('payments_id_seq'), 21, true

Dies gibt einen Fehler:

ERROR: function setval(unknown) does not exist

Verwenden ALTER SEQUENCEscheint auch nicht zu funktionieren?

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Wie kann das gemacht werden?

Ref: https://www.postgresql.org/docs/current/static/functions-sequence.html


4
Es scheint, dass setval()mindestens zwei Argumente hat.

Antworten:


259

Die Klammern sind falsch platziert:

SELECT setval('payments_id_seq', 21, true);  # next value will be 22

Andernfalls rufen Sie setvalmit einem einzelnen Argument auf, während zwei oder drei erforderlich sind.


2
Was bedeutet das letzte Argument "wahr"?
Inafalcao

15
true bedeutet, dass der nächste Wert die angegebene Zahl + 1 ist, in diesem Fall 22. false bedeutet, dass der nächste Wert die angegebene Zahl ist, oder 21. Standardmäßig verhält sich setval so, als ob trueausgewählt wurde. Weitere Details: postgresql.org/docs/9.6/static/functions-sequence.html
Tom Mertz

1
ein Vorteil der select setval Syntax gegenüber Tatsache, alter sequencedass Sie darin verschachtelte Abfragen verwenden können, z. B. to select max(id) from payments.
Mariotomo

182

Diese Syntax ist in keiner Version von PostgreSQL gültig :

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Das würde funktionieren:

ALTER SEQUENCE payments_id_seq RESTART WITH 22;

und entspricht:

SELECT setval('payments_id_seq', 22, FALSE);

Mehr im aktuellen Handbuch für ALTER SEQUENCEund Sequenzfunktionen .

Beachten Sie, setval()dass entweder erwartet(regclass, bigint) oder(regclass, bigint, boolean) . Im obigen Beispiel stelle ich untypisierte Literale bereit . Das funktioniert auch. Wenn Sie der Funktion jedoch typisierte Variablen zuführen, benötigen Sie möglicherweise explizite Typumwandlungen , um die Auflösung des Funktionstyps zu erfüllen. Mögen:

SELECT setval(my_text_variable::regclass, my_other_variable::bigint, FALSE);

Für wiederholte Operationen könnten Sie interessiert sein an:

ALTER SEQUENCE payments_id_seq START WITH 22; -- set default
ALTER SEQUENCE payments_id_seq RESTART;       -- without value

START [WITH] speichert einen Standard RESTART , die für nachfolgende RESTARTAnrufe ohne Wert verwendet wird. Für den letzten Teil benötigen Sie Postgres 8.4 oder höher.


4
ALTER SEQUENCE [sequence] RESTART WITH (SELECT MAX(col) from table);funktioniert nicht, wohingegen SELECT setval('sequence', (SELECT (MAX(col) from table), TRUE);funktioniert. Ich erhalte einen Syntaxfehler. (Postgres 9.4)
NuclearPeon

1
In einem DDL-Befehl ("Utility-Befehl") ist keine Unterabfrage zulässig. Siehe: stackoverflow.com/a/36025963/939860
Erwin Brandstetter

1
@MitalPritmani: Möglicherweise benötigen Sie Typumwandlungen. Beachten Sie die obigen Anweisungen.
Erwin Brandstetter

1
@ NuclearPeon Ich denke du meinst, SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);sonst richten sich deine Eltern nicht aus.
Dland

1
@dland: Nebenbei: kürzeres und schnelleres Äquivalent: SELECT setval('seq', max(col)) FROM tbl;Siehe: stackoverflow.com/a/23390399/939860
Erwin Brandstetter

33

Verwenden select setval('payments_id_seq', 21, true);

setval enthält 3 Parameter:

  • 1. Parameter ist sequence_name
  • 2. Parameter ist Weiter nextval
  • Der dritte Parameter ist optional.

Die Verwendung von true oder false im 3. Parameter von setval ist wie folgt:

SELECT setval('payments_id_seq', 21);           // Next nextval will return 22
SELECT setval('payments_id_seq', 21, true);     // Same as above 
SELECT setval('payments_id_seq', 21, false);    // Next nextval will return 21

Der bessere Weg, um eine harte Codierung des Sequenznamens und des nächsten Sequenzwerts zu vermeiden und die leere Spaltentabelle korrekt zu behandeln, ist der folgende Weg:

SELECT setval(pg_get_serial_sequence('table_name', 'id'), coalesce(max(id), 0)+1 , false) FROM table_name;

wo table_nameist der Name der Tabelle, iddie primary keyvon der Tabelle


Danke dir! Der letzte Ausdruck ist genau das, wonach ich gesucht habe. Dadurch kann ich die Sequenzwerte reservieren, um sie anschließend stapelweise einzufügen.
Timur


0

Ich versuche nicht, die Reihenfolge über zu ändern setval. Aber mit wurde ALTERmir ausgestellt, wie man den Sequenznamen richtig schreibt. Und das funktioniert nur bei mir:

  1. Überprüfen Sie den gewünschten Sequenznamen mit SELECT * FROM information_schema.sequences;

  2. ALTER SEQUENCE public."table_name_Id_seq" restart {number};

    In meinem Fall war es ALTER SEQUENCE public."Services_Id_seq" restart 8;

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.