ERROR: more than one owned sequence found in Postgres

ERROR: more than one owned sequence found in Postgres

我正在为 Patient table.
的现有列设置标识列 在这里我想使用 GENERATED ALWAYS AS IDENTITY.

所以我使用以下语句设置标识列(以前是 serial):

ALTER TABLE Patient ALTER PatientId
   ADD GENERATED ALWAYS AS IDENTITY (START WITH 1);

现有患者table我总共有5条记录。 (patientId 1 到 5)
当我在身份设置后插入一条新记录时,它会抛出如下错误:

more than one owned sequence found

即使在重置标识列之后,我仍然遇到相同的错误。

ALTER TABLE Patient ALTER COLUMN PatientId RESTART WITH 6;

如果您有任何解决方案,请告诉我。

更新: 此错误已在 PostgreSQL v12 中通过提交 19781729f78.
修复 其余答案与旧版本相关。

一个 serial 列有一个属于该列的序列和一个获得净序列值的 DEFAULT 值。

如果您尝试将该列更改为标识列,您将收到一条错误消息,提示该列已有默认值。

现在您必须删除默认值,但不删除属于 serial 列的序列。然后,当您将该列转换为标识列时,将创建该列拥有的第二个序列。

现在,当您尝试插入一行时,PostgreSQL 会尝试查找并使用该列拥有的 序列,但是有两个,因此出现错误消息。

我认为这是 PostgreSQL 中的一个错误:在我看来,它应该为标识列重新调整现有序列的用途,或者给您一个错误,表明该列已经拥有一个序列,并且你应该放弃它。 I'll try to get this bug fixed.

同时,您应该手动删除 serial 列中留下的序列。 运行 以下查询:

SELECT d.objid::regclass
FROM pg_depend AS d
   JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                             d.refobjsubid = a.attnum
WHERE d.classid = 'pg_class'::regclass
  AND d.refclassid = 'pg_class'::regclass
  AND d.deptype <> 'i'
  AND a.attname = 'patientid'
  AND d.refobjid = 'patient'::regclass;

那应该给你 serial 列留下的序列的名称。删除它,标识列应该按预期运行。

这不是答案 -- 抱歉,但这让我能够以生动的形象展示我今天早上(无意中)发现的疯狂行为...

我所要做的就是:

alter TABLE db.generic_items alter column generic_item_id drop default;
alter TABLE db.generic_items alter column generic_item_id add generated by default as identity;

现在,在将 table 编写为 SQL 的脚本时,我得到(缩写):

CREATE TABLE db.generic_items
(
    generic_item_id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    generic_item_id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    generic_item_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT pk_generic_items PRIMARY KEY (generic_item_id),
)

感谢 Laurenz Albe 在上面发布的 answer!正如他解释的那样,只需删除用于串行默认值的序列,这种疯狂就会消失,table 看起来又正常了。

同样,这不是答案,但评论并没有让我添加足够的文本。 道歉。继续我之前的评论。 这是我执行的,它表明,imo,手动修复是不够的,对于大表,我使用的重复技巧(见下文)是不切实际的,并且可能是错误的,因为采用了属于已删除行的 id。

-- pls disregard the absence of 2 id rows, this is the final situation    
\d vaste_data.studie_type
                                  Table "vaste_data.studie_type"
     Column |         Type          | Collation | Nullable |             Default
    --------+-----------------------+-----------+----------+----------------------------------
     id     | integer               |           | not null | generated by default as identity
     naam   | character varying(25) |           | not null |
    Indexes:
        "pk_tstudytype_tstudytype_id" PRIMARY KEY, btree (id)
    Referenced by:
        TABLE "stuwadoors" CONSTRAINT "fk_t_stuwadoors_t_studytype" FOREIGN KEY (study_type_id) REFERENCES vaste_data.studie_type(id)
        TABLE "psux" CONSTRAINT "study_studytype_fk" FOREIGN KEY (studie_type_id) FOREIGN KEY (studie_type_id) REFERENCES vaste_data.studie_type(id)
    
    alter table vaste_data.studie_type alter column id drop default;
    ALTER TABLE
    alter table vaste_data.studie_type alter column id add generated by default as identity;
    ALTER TABLE
    -- I chose to show both sequences so I could try to drop either one.
    SELECT d.objid::regclass
    FROM pg_depend AS d
       JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                                 d.refobjsubid = a.attnum
    WHERE d.classid = 'pg_class'::regclass
      AND d.refclassid = 'pg_class'::regclass
      AND a.attname = 'id'
      AND d.refobjid = 'vaste_data.studie_type'::regclass;
                      objid
    -----------------------------------------
     vaste_data.studie_type_id_seq
     vaste_data.tstudytype_tstudytype_id_seq
    (2 rows)
    
    drop sequence vaste_data.studie_type_id_seq;
    ERROR:  cannot drop sequence vaste_data.studie_type_id_seq because column id of table vaste_data.studie_type requires it
    HINT:  You can drop column id of table vaste_data.studie_type instead.
    
    \d vaste_data.studie_type_id_seq
                   Sequence "vaste_data.studie_type_id_seq"
      Type   | Start | Minimum |  Maximum   | Increment | Cycles? | Cache
    ---------+-------+---------+------------+-----------+---------+-------
     integer |     1 |       1 | 2147483647 |         1 | no      |     1
    Sequence for identity column: vaste_data.studie_type.id
    
    alter sequence vaste_data.studie_type_id_seq start 6;
    ALTER SEQUENCE
    drop sequence vaste_data.tstudytype_tstudytype_id_seq;
    DROP SEQUENCE
    insert into vaste_data.studie_type (naam) values('Overige leiding');
    ERROR:  duplicate key value violates unique constraint "pk_tstudytype_tstudytype_id"
    DETAIL:  Key (id)=(1) already exists.
    ...
    ERROR:  duplicate key value violates unique constraint "pk_tstudytype_tstudytype_id"
    DETAIL:  Key (id)=(5) already exists.
    insert into vaste_data.studie_type (naam) values('Overige leiding');
    INSERT 0 1