主键序列不存在

时间:2016-07-01 09:14:18

标签: postgresql primary-key sequence auto-increment

我有一个postgresql数据库,在迁移到更新版本并导入旧数据后,我遇到了主键问题:

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint   
"browser_link_pkey"  Detail: Key (id)=(173) already exists.

所以我想重置我的序列,但是运行:

select nextval('browser_link_id_seq')

也失败了:

column „browser_link_id_seq“ does not exist
SQL Status:42703

这是用于创建表的SQL

CREATE TABLE browser_link (
    id bigint NOT NULL,
....
);
ALTER TABLE ONLY browser_link
ADD CONSTRAINT browser_link_pkey PRIMARY KEY (id);

我尝试选择序列序列,但似乎不存在:

postgres=# \connect historify
You are now connected to database "historify" as user "postgres".
historify=# select pg_get_serial_sequence('browser_link', 'id');
 pg_get_serial_sequence
------------------------

(1 row)

我正在使用postgresql 9.5.3。此外,直到发生错误,id列确实按预期增加,所以它确实有效。

现在我的两个问题:

  1. 为什么自动增量有效?
  2. 如何重置自动增量计数器?

1 个答案:

答案 0 :(得分:1)

Postgres中的序列是整数,默认由序列提供。 在下面的片段中,表“one”和表“two”完全等效:

CREATE TABLE one
( id bigserial NOT NULL PRIMARY KEY
  , name varchar
);

CREATE TABLE two
( id bigint NOT NULL PRIMARY KEY
  , name varchar
);
CREATE SEQUENCE "two_id_seq"
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;

ALTER SEQUENCE "two_id_seq"
        OWNED BY two.id
        ;
ALTER TABLE two
        ALTER COLUMN id SET default nextval('two_id_seq')
        ;

\d one
\d two

如您所见,serial表的one语法更紧凑(它实际上是two表所需的4个语句的简写符号)< / p>

因此,在您的问题表中,您可以使用bigserial而不是bigint作为数据类型重建表格,或者通过“{”将现有序列“附加”到现有idALTER table ... ALTER COLUMN ...语法。

您可以通过'setval('name',val)将序列设置为新值;`example:

INSERT INTO two(id, name) VALUES ( 13, 'thirteen' );
select nextval('two_id_seq');
SELECT setval ('two_id_seq', (select max(id) FROM two));
select * from two;
select nextval('two_id_seq');

结果:

INSERT 0 1
 nextval 
---------
       1
(1 row)

 setval 
--------
     13
(1 row)

 id |   name   
----+----------
 13 | thirteen
(1 row)

 nextval 
---------
      14
(1 row)