当我试图使用alter命令更改表中列的数据类型时...
alter table temp alter column id type bigserial;
我理解了
ERROR: type "bigserial" does not exist
如何将数据类型从bigint更改为bigserial?
当我试图使用alter命令更改表中列的数据类型时...
alter table temp alter column id type bigserial;
我理解了
ERROR: type "bigserial" does not exist
如何将数据类型从bigint更改为bigserial?
正如 文档 中所解释的那样,SERIAL
不是一种数据类型,而是一组其他命令的快捷方式。
因此,虽然您不能通过更改类型来简单地更改它,但您可以通过自己运行这些其他命令来实现相同的效果:
CREATE SEQUENCE temp_id_seq;
ALTER TABLE temp ALTER COLUMN id SET NOT NULL;
ALTER TABLE temp ALTER COLUMN id SET DEFAULT nextval('temp_id_seq');
ALTER SEQUENCE temp_id_seq OWNED BY temp.id;
更改所有者将确保如果表/列被删除,则序列会被删除。同时,它也会给予您在pg_get_serial_sequence()函数中期望的行为。
坚持使用tablename_columnname_seq
命名约定是必要的,以便使一些工具(如pgAdmin)报告此列类型为BIGSERIAL
。请注意,即使列最初声明为SERIAL
类型,psql和pg_dump也将始终显示基础定义。
截至Postgres 10,您还可以选择使用SQL标准的identity column,它可隐式处理所有这些,并且可以轻松地添加到现有表中:
ALTER TABLE temp ALTER COLUMN id
ADD GENERATED BY DEFAULT AS IDENTITY
将列从BIGINTEGER
更改为BIGSERIAL
以使其自动递增是行不通的。BIGSERIAL
不是真正的类型,而是一种可以自动创建PK
和SEQUENCE
的技巧。
相反,您可以自己创建一个序列,然后将其分配为列的默认值:
CREATE SEQUENCE "YOURSCHEMA"."SEQNAME";
ALTER TABLE "YOURSCHEMA"."TABLENAME"
ALTER COLUMN "COLUMNNAME" SET DEFAULT nextval('"YOURSCHEMA"."SEQNAME"'::regclass);
ALTER TABLE "YOURSCHEMA"."TABLENAME" ADD CONSTRAINT pk PRIMARY KEY ("COLUMNNAME");
PRIMARY KEY
约束将失败。(假设用户尚未具有主键。SERIAL
不仅适用于主键,且SERIAL
不意味着SERIAL PRIMARY KEY
)。此外,如果表中存在行,则需要使用setval
序列来确保它从第一个空闲标识符开始,并首先锁定表以防止并发的INSERT
s。 - Craig RingerALTER TABLE table_name drop column column_name, add column column_name bigserial;
听起来好像有很多专业人士在这个问题上......如果原始表确实有数据,那么解决这个困境的真正答案是在第一次正确设计数据库。然而,既然如此,更改列规则(类型)将需要验证该列的完整性以适应新范例。而且,不要忘记,任何操作该列的地方(添加/更新)都需要进行检查。
如果这是一个新表,那么可以简单地删除列并重新添加新列(为您处理序列)。同样,设计,设计,设计。
我想我们都犯过这种错误。
SERIAL
类型。如果您查看具有BIGSERIAL
的表的pg_dump
输出,您将只看到一个BIGINT
和一个序列(自己创建BIGINT
和序列与使用BIGSERIAL
关键字完全相同)。需要注意的是,从Postgres 10开始,您可以选择将其转换为身份列。 - Nick Barnes