Postgres mengubah urutan secara manual

189

Saya mencoba mengatur urutan ke nilai tertentu.

SELECT setval('payments_id_seq'), 21, true

Ini memberikan kesalahan:

ERROR: function setval(unknown) does not exist

Menggunakan ALTER SEQUENCEsepertinya juga tidak berhasil?

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Bagaimana ini bisa dilakukan?

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

Stefan
sumber
4
Tampaknya setval()paling tidak ada dua argumen.

Jawaban:

262

Tanda kurung salah tempat:

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

Kalau tidak, Anda menelepon setvaldengan satu argumen, sementara itu membutuhkan dua atau tiga.

NPE
sumber
2
Apa arti argumen "benar" terakhir?
inafalcao
15
trueberarti bahwa nilai berikutnya adalah angka yang diberikan +1, dalam hal ini 22. falseberarti nilai berikutnya adalah angka yang disediakan, atau 21. Secara default, setval akan berperilaku seolah-olah truetelah dipilih. Lebih detail: postgresql.org/docs/9.6/static/functions- berikutnyaence.html
Tom Mertz
1
keuntungan dari select setvalsintaks lebih alter sequenceadalah bahwa Anda dapat menggunakan kueri bersarang di dalamnya, misalnya untuk select max(id) from payments.
mariotomo
187

Sintaks ini tidak valid dalam versi PostgreSQL apa pun :

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Ini akan berhasil:

ALTER SEQUENCE payments_id_seq RESTART WITH 22;

dan setara dengan:

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

Lebih banyak di manual saat ini untuk ALTER SEQUENCEdan fungsi urutan .

Catatan yang setval()mengharapkan salah satu (regclass, bigint)atau (regclass, bigint, boolean). Dalam contoh di atas saya menyediakan literal yang belum diketik . Itu juga berhasil. Tetapi jika Anda memasukkan variabel yang diketik ke fungsi, Anda mungkin perlu cetakan tipe eksplisit untuk memenuhi resolusi tipe fungsi. Suka:

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

Untuk operasi berulang Anda mungkin tertarik pada:

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

START [WITH]menyimpan RESTARTnomor default , yang digunakan untuk RESTARTpanggilan berikutnya tanpa nilai. Anda memerlukan Postgres 8.4 atau lebih baru untuk bagian terakhir.

Erwin Brandstetter
sumber
4
ALTER SEQUENCE [sequence] RESTART WITH (SELECT MAX(col) from table);tidak bekerja, sedangkan SELECT setval('sequence', (SELECT (MAX(col) from table), TRUE);bekerja. Saya mendapatkan kesalahan sintaksis. (Postgres 9.4)
NuclearPeon
1
Subquery tidak diizinkan dalam perintah DDL ("perintah utilitas"). Lihat: stackoverflow.com/a/36025963/939860
Erwin Brandstetter
1
@MitalPritmani: Anda mungkin perlu mengetikkan gips. Pertimbangkan instruksi tambahan di atas.
Erwin Brandstetter
1
@NuclearPeon Saya pikir maksud Anda SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);jika orang tua Anda tidak berbaris.
dland
1
@ tanah: Selain: setara lebih pendek & lebih cepat: SELECT setval('seq', max(col)) FROM tbl;Lihat: stackoverflow.com/a/23390399/939860
Erwin Brandstetter
33

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

setval berisi 3 parameter:

  • Parameter 1 adalah sequence_name
  • Parameter 2 adalah Berikutnya nextval
  • Parameter ke-3 adalah opsional.

Penggunaan true atau false pada parameter ke-3 dari setval adalah sebagai berikut:

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

Cara yang lebih baik untuk menghindari pengkodean nama urutan, nilai urutan berikutnya dan untuk menangani tabel kolom kosong dengan benar, Anda dapat menggunakan cara di bawah ini:

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

di mana table_namenama tabel, idadalah primary keytabel

VaibsVB
sumber
Terima kasih! Ekspresi terakhir adalah persis apa yang saya cari. Ini memungkinkan saya untuk memesan nilai-nilai urutan untuk memasukkan secara batch sesudahnya.
Timur
8
setval('sequence_name', sequence_value)
Andrzej Bobak
sumber
0

Saya tidak mencoba mengubah urutan melalui setval. Tetapi dengan menggunakan ALTERsaya dikeluarkan bagaimana menulis nama urutan dengan benar. Dan ini hanya bekerja untuk saya:

  1. Periksa nama urutan yang diperlukan menggunakan SELECT * FROM information_schema.sequences;

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

    Dalam kasus saya itu ALTER SEQUENCE public."Services_Id_seq" restart 8;

alanextar
sumber