Postgres modifica manualmente la sequenza


189

Sto cercando di impostare una sequenza su un valore specifico.

SELECT setval('payments_id_seq'), 21, true

Questo dà un errore:

ERROR: function setval(unknown) does not exist

Usando ALTER SEQUENCEnon sembra funzionare neanche?

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Come si può fare?

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


4
Sembrerebbe che setval()abbia almeno due argomenti.

Risposte:


262

Le parentesi sono fuori posto:

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

Altrimenti stai chiamando setvalcon un singolo argomento, mentre ne richiedono due o tre.


2
Cosa significa l'ultimo argomento "vero"?
Inafalcao,

15
truesignifica che il valore successivo sarà il numero fornito + 1, in questo caso 22. falsesignifica che il valore successivo sarebbe il numero fornito, oppure 21. Per impostazione predefinita, setval si comporterà come se truefosse stato scelto. Maggiori dettagli: postgresql.org/docs/9.6/static/functions-sequence.html
Tom Mertz

1
un vantaggio della select setvalsintassi alter sequenceè che è possibile utilizzare query nidificate al suo interno, ad esempio select max(id) from payments.
mariotomo,

187

Questa sintassi non è valida in nessuna versione di PostgreSQL:

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Questo funzionerebbe:

ALTER SEQUENCE payments_id_seq RESTART WITH 22;

ed è equivalente a:

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

Maggiori informazioni nel manuale attuale per ALTER SEQUENCEe funzioni di sequenza .

Si noti che setval()prevede uno (regclass, bigint)o (regclass, bigint, boolean). Nell'esempio sopra sto fornendo letterali non tipizzati . Anche questo funziona. Ma se si alimentano variabili digitate alla funzione, potrebbe essere necessario eseguire cast di tipi espliciti per soddisfare la risoluzione del tipo di funzione. Piace:

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

Per operazioni ripetute potresti essere interessato a:

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

START [WITH]memorizza un RESTARTnumero predefinito , che viene utilizzato per le RESTARTchiamate successive senza valore. Per l'ultima parte è necessario Postgres 8.4 o successivo.


4
ALTER SEQUENCE [sequence] RESTART WITH (SELECT MAX(col) from table);non funziona, mentre SELECT setval('sequence', (SELECT (MAX(col) from table), TRUE);funziona. Ottengo un errore di sintassi. (Postgres 9.4)
NuclearPeon

1
Nessuna subquery consentita in un comando DDL ("comando utility"). Vedi: stackoverflow.com/a/36025963/939860
Erwin Brandstetter,

1
@MitalPritmani: potresti aver bisogno di cast di tipo. Considera le istruzioni aggiunte sopra.
Erwin Brandstetter,

1
@NuclearPeon Penso che intendi SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);altrimenti i tuoi genitori non si allineano.
dland

1
@dland: a parte: equivalente più breve e più veloce: SELECT setval('seq', max(col)) FROM tbl;vedi: stackoverflow.com/a/23390399/939860
Erwin Brandstetter

33

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

setval contiene 3 parametri:

  • 1 ° parametro è sequence_name
  • Il secondo parametro è Next nextval
  • 3 ° parametro è facoltativo.

L'uso di vero o falso nel terzo parametro di setval è il seguente:

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

Il modo migliore per evitare la codifica definitiva del nome della sequenza, il valore della sequenza successiva e gestire correttamente la tabella di colonne vuota, è possibile utilizzare il modo seguente:

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

dove table_nameè il nome della tabella, idè il primary keydella tabella


Grazie! L'ultima espressione è esattamente quello che stavo cercando. Mi consente di riservare i valori di sequenza per poterli inserire successivamente in batch.
Timur,


0

Non provo a cambiare sequenza tramite setval. Ma usando ALTERmi è stato rilasciato come scrivere correttamente il nome della sequenza. E questo funziona solo per me:

  1. Verificare il nome della sequenza richiesta utilizzando SELECT * FROM information_schema.sequences;

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

    Nel mio caso lo era ALTER SEQUENCE public."Services_Id_seq" restart 8;

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.