pg_get_serial_sequencedapat digunakan untuk menghindari asumsi yang salah tentang nama urutan. Ini mengatur ulang urutan dalam satu pemotretan:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), (SELECT MAX(id) FROM table_name)+1);
Atau lebih ringkas:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), MAX(id)) FROM table_name;
Namun formulir ini tidak dapat menangani tabel kosong dengan benar, karena maks (id) adalah nol, dan Anda juga tidak dapat menetapkan 0 karena itu akan berada di luar kisaran urutan. Salah satu solusi untuk ini adalah dengan menggunakanALTER SEQUENCE sintaks yaitu
ALTER SEQUENCE table_name_id_seq RESTART WITH 1;
ALTER SEQUENCE table_name_id_seq RESTART; -- 8.4 or higher
Tetapi ALTER SEQUENCEpenggunaannya terbatas karena nama urutan dan nilai restart tidak dapat berupa ekspresi.
Tampaknya solusi serba guna terbaik adalah memanggil setvaldengan false sebagai parameter ke-3, memungkinkan kami menentukan "nilai selanjutnya yang akan digunakan":
SELECT setval(pg_get_serial_sequence('t1', 'id'), coalesce(max(id),0) + 1, false) FROM t1;
Ini mencentang semua kotak saya:
- menghindari pengodean nama urutan yang sebenarnya
- menangani tabel kosong dengan benar
- menangani tabel dengan data yang ada, dan tidak meninggalkan lubang dalam urutan
Akhirnya, perhatikan bahwa pg_get_serial_sequencehanya berfungsi jika urutan dimiliki oleh kolom. Ini akan menjadi kasus jika kolom tambahan didefinisikan sebagai serialtipe, namun jika urutan ditambahkan secara manual maka perlu untuk memastikanALTER SEQUENCE .. OWNED BY juga dilakukan.
yaitu jika serialjenis digunakan untuk pembuatan tabel, ini semua harus bekerja:
CREATE TABLE t1 (
id serial,
name varchar(20)
);
SELECT pg_get_serial_sequence('t1', 'id'); -- returns 't1_id_seq'
-- reset the sequence, regardless whether table has rows or not:
SELECT setval(pg_get_serial_sequence('t1', 'id'), coalesce(max(id),0) + 1, false) FROM t1;
Tetapi jika urutan ditambahkan secara manual:
CREATE TABLE t2 (
id integer NOT NULL,
name varchar(20)
);
CREATE SEQUENCE t2_custom_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE t2 ALTER COLUMN id SET DEFAULT nextval('t2_custom_id_seq'::regclass);
ALTER SEQUENCE t2_custom_id_seq OWNED BY t2.id; -- required for pg_get_serial_sequence
SELECT pg_get_serial_sequence('t2', 'id'); -- returns 't2_custom_id_seq'
-- reset the sequence, regardless whether table has rows or not:
SELECT setval(pg_get_serial_sequence('t2', 'id'), coalesce(max(id),0) + 1, false) FROM t1;