我正在为Patient
表的现有列设置一个标识列。
在这里,我想使用始终作为身份标识。
因此,我使用以下语句(以前是serial
)来设置标识列:
ALTER TABLE Patient ALTER PatientId
ADD GENERATED ALWAYS AS IDENTITY (START WITH 1);
对于现有的患者表,我总共有5条记录。 (patientId
1到5)
当我在身份设置后插入新记录时,它将引发类似以下错误:
more than one owned sequence found
即使重置了身份列,我仍然遇到相同的错误。
ALTER TABLE Patient ALTER COLUMN PatientId RESTART WITH 6;
让我知道您是否有解决方案。
答案 0 :(得分:1)
serial
列具有该列所拥有的序列和一个获取净序列值的DEFAULT
值。
如果您尝试将该列更改为身份列,则会收到错误消息,指出该列已经具有默认值。
现在,您必须删除默认值,但不能删除属于serial
列的序列。然后,当您将列转换为身份列时,将创建该列拥有的第二个序列。
现在,当您尝试插入行时,PostgreSQL尝试查找并使用该列拥有的 the 序列,但是有两个序列,因此是错误消息。
我认为这是PostgreSQL中的错误:我认为,它应该已将Identity列的现有序列重新利用,或者给您一个错误,即该列已拥有一个序列,您应该算了吧。 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
列中留下的序列的名称。放下它,标识列应具有预期的作用。
答案 1 :(得分:0)
这不是一个答案-道歉,但是这使我可以生动地表现我今天早上(无意间)发现的疯狂行为...
我要做的就是这个:
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;
现在将表编写为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 表示感谢!正如他解释的那样,只需删除用于序列默认值的序列,这种疯狂就消失了,表格又恢复了正常。