pg_get_serial_sequence
dizi adı ile ilgili yanlış varsayımlardan kaçınmak için kullanılabilir. Bu, bir çekimde sekansı sıfırlar:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), (SELECT MAX(id) FROM table_name)+1);
Ya da daha kısaca:
SELECT pg_catalog.setval(pg_get_serial_sequence('table_name', 'id'), MAX(id)) FROM table_name;
Ancak bu form boş tabloları düzgün işleyemez, çünkü max (id) boştur ve dizinin kapsamı dışında olacağı için 0 değerini de ayarlayamazsınız. Bunun bir çözümü ALTER SEQUENCE
sözdizimine başvurmaktır.
ALTER SEQUENCE table_name_id_seq RESTART WITH 1;
ALTER SEQUENCE table_name_id_seq RESTART; -- 8.4 or higher
Ancak ALTER SEQUENCE
, sıra adı ve yeniden başlatma değeri ifadeler olamayacağı için sınırlı kullanımlıdır.
En iyi çok amaçlı çözüm, setval
3. parametre olarak false ile çağırmak ve "kullanılacak sonraki değeri" belirtmemize izin vermek gibi görünüyor :
SELECT setval(pg_get_serial_sequence('t1', 'id'), coalesce(max(id),0) + 1, false) FROM t1;
Bu benim tüm kutuları keneler:
- gerçek dizi adının sabit kodlanmasını önler
- boş tabloları doğru şekilde işler
- varolan verileri içeren tabloları işler ve sırada bir boşluk bırakmaz
Son olarak, pg_get_serial_sequence
yalnızca dizinin sütuna ait olması durumunda işe yaradığını unutmayın . Bu, artan sütunun bir serial
tür olarak tanımlanması durumunda olacaktır , ancak dizi manuel olarak eklenmişse,ALTER SEQUENCE .. OWNED BY
.
örneğin, serial
tür tablo oluşturmak için kullanıldıysa, bunların tümü çalışmalıdır:
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;
Ancak sekanslar manuel olarak eklendiyse:
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;