pg_get_serial_sequence
dapat 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 SEQUENCE
penggunaannya terbatas karena nama urutan dan nilai restart tidak dapat berupa ekspresi.
Tampaknya solusi serba guna terbaik adalah memanggil setval
dengan 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_sequence
hanya berfungsi jika urutan dimiliki oleh kolom. Ini akan menjadi kasus jika kolom tambahan didefinisikan sebagai serial
tipe, namun jika urutan ditambahkan secara manual maka perlu untuk memastikanALTER SEQUENCE .. OWNED BY
juga dilakukan.
yaitu jika serial
jenis 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;