我有一个包含现有数据的表格。有没有办法在不删除和重新创建表的情况下添加主键?
(已更新 - 感谢评论的人)
假设您有一个名为
test1
的表,您想要向其中添加一个自动递增的主键 id
(代理)列。在最新版本的 PostgreSQL 中,以下命令应该足够了:
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
在旧版本的 PostgreSQL(8.x 之前?)中,你必须做所有肮脏的工作。以下命令序列应该可以解决问题:
ALTER TABLE test1 ADD COLUMN id INTEGER;
CREATE SEQUENCE test_id_seq OWNED BY test1.id;
ALTER TABLE test1 ALTER COLUMN id SET DEFAULT nextval('test_id_seq');
UPDATE test1 SET id = nextval('test_id_seq');
同样,在最新版本的 Postgres 中,这大致相当于上面的单个命令。
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
这就是您所需要的:
id
列感谢@resnyanskiy,他在评论中给出了这个答案。
要在 v10 中使用标识列,
ALTER TABLE test
ADD COLUMN id { int | bigint | smallint}
GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY PRIMARY KEY;
有关标识列的说明,请参阅 https://blog.2ndquadrant.com/postgresql-10-identity-columns/。
有关 GENERATED BY DEFAULT 和 GENERATED ALWAYS 之间的区别,请参阅 https://www.cybertec-postgresql.com/en/sequences-gains-and-pitfalls/。
要更改序列,请参阅 https://popsql.io/learn-sql/postgresql/how-to-alter-sequence-in-postgresql/。
我来到这里是因为我也在寻找类似的东西。就我而言,我将数据从一组具有许多列的临时表复制到一个表中,同时还将行 ID 分配给目标表。这是我使用的上述方法的变体。 我在目标表的末尾添加了序列列。这样我就不必在 Insert 语句中为其添加占位符。然后简单的 select * into 目标表自动填充此列。这是我在 PostgreSQL 9.6.4 上使用的两条 SQL 语句。
ALTER TABLE target ADD COLUMN some_column SERIAL;
INSERT INTO target SELECT * from source;
ALTER TABLE test1 ADD id int8 NOT NULL GENERATED ALWAYS AS IDENTITY;
我知道已经过去很多年了,但这可能会对其他用户有所帮助。 尝试使用第一个查询:
ALTER TABLE dbo."Users"
ALTER COLUMN "UserID"
ADD GENERATED BY DEFAULT AS IDENTITY (MINVALUE 1 START WITH 1 INCREMENT BY 1)
第二次查询更新当前值:
SELECT setval('"Users_UserID_seq"', (SELECT max("UserID")+1 FROM dbo."Users"), false)
其中“Users”-表,“UserID”-主键