无法在 PostgreSQL 中设置序列的起始值

Cannot set start value of sequence in PostgreSQL

提问人:Jack 提问时间:3/16/2023 最后编辑:Jack 更新时间:3/16/2023 访问量:129

问:

我在Spring Boot应用程序中使用迁移脚本并创建一个序列,如下所示:

CREATE SEQUENCE IF NOT EXISTS public.sequence_user START WITH 4 INCREMENT BY 5;

然后,在另一个迁移文件中,我通过以下脚本插入 3 个用户:

INSERT INTO public.user (id, first_name, last_name, username, "password")
VALUES (1, 'John', 'Doe', 'johndoe', '...');
INSERT INTO public.user (id, first_name, last_name, username, "password")
VALUES (2, 'Frank', 'James', 'frank', '...');
INSERT INTO public.user (id, first_name, last_name, username, "password")
VALUES (3, 'Foo', 'Bar', 'foo', '...');

ALTER SEQUENCE sequence_user RESTART;
UPDATE public.user SET id = DEFAULT;

但是,当我运行我的应用程序并尝试添加新用户时,此用户 ID 取为 0,然后取 1,这引发了错误。那么,我怎样才能让这个序列开始给出 4 的数字?

更新:Create Table 语句:

CREATE SEQUENCE IF NOT EXISTS public.sequence_user START WITH 1 INCREMENT BY 5;


CREATE TABLE public."user"
(
    id         BIGINT       NOT NULL,
    first_name VARCHAR(50)  NOT NULL,
    last_name  VARCHAR(50)  NOT NULL,
    username   VARCHAR(20)  NOT NULL,
    password   VARCHAR(100) NOT NULL,
    CONSTRAINT pk_user PRIMARY KEY (id)
);
Java Spring PostgreSQL 序列 飞行路线

评论

0赞 user_0 3/16/2023
您需要将列链接到序列,例如使用 OWNED BY
0赞 Jack 3/16/2023
ALTER SEQUENCE sequence_user RESTART WITH 4;-->不工作
0赞 Jack 3/16/2023
SELECT setval(''sequence_user'', max(id)) FROM public.user;--> 错误:“sequence_user”处或附近出现语法错误

答:

1赞 Zegarek 3/16/2023 #1

要将序列移动到任意位置,可以使用 setval():

select setval('public.sequence_user',
              (select max(id) from public.user) );

请注意,INCREMENT BY 5 表示序列将始终以 5 的步长向前移动。您还可以将序列正确地链接到列:

alter sequence public.sequence_user owned by public.user.id;
alter table public.user 
   alter column id 
   set default nextval('public.sequence_user');
select setval(pg_get_serial_sequence('public.user','id'),
              (select max(id) from public.user) );

最好让数据库创建、处理和维护您的序列:id

create table public.user (
   id int generated by default as identity primary key, 
   first_name text, 
   last_name  text, 
   username   text, 
   "password" text);

select pg_get_serial_sequence('public.user','id');--public.user_id_seq

在这两种情况下,序列都会成为默认值的生成器,但仍然允许您插入自己的行,只要您事后通知它: demo

insert into public.user (id, first_name, last_name, username, "password")
values 
  (1, 'John', 'Doe', 'johndoe', '...')
, (2, 'Frank', 'James', 'frank', '...')
, (3, 'Foo', 'Bar', 'foo', '...');

select setval(pg_get_serial_sequence('public.user','id'),
              (select max(id) from public.user) );

insert into public.user (id, first_name, last_name, username, "password")
values (default, 'Adam', 'Savage', 'adamsavage', '...');

insert into public.user (first_name, last_name, username, "password")
values ('Adam', 'Sandler', 'adamsandler', '...');

评论

0赞 Jack 3/16/2023
多谢。 也解决了问题。SELECT setval('sequence_user', max(id)) FROM public.user;