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
我正在为 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