如何在PostgreSQL中向现有表添加自动递增主键?

如何在PostgreSQL中向现有表添加自动递增主键?,postgresql,primary-key,auto-increment,Postgresql,Primary Key,Auto Increment,我有一个包含现有数据的表。有没有一种方法可以在不删除和重新创建表的情况下添加主键?(更新-感谢发表评论的人) PostgreSQL的现代版本 假设您有一个名为test1的表,您想在其中添加一个自动递增的主键id(代理)列。在最新版本的PostgreSQL中,以下命令应足够: ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY; PostgreSQL的旧版本 在旧版本的PostgreSQL(8.x之前?)中,您必须完成所有的脏活。下面的命令

我有一个包含现有数据的表。有没有一种方法可以在不删除和重新创建表的情况下添加主键?

(更新-感谢发表评论的人)

PostgreSQL的现代版本 假设您有一个名为
test1
的表,您想在其中添加一个自动递增的主键
id
(代理)列。在最新版本的PostgreSQL中,以下命令应足够:

   ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
PostgreSQL的旧版本 在旧版本的PostgreSQL(8.x之前?)中,您必须完成所有的脏活。下面的命令序列应该可以做到这一点:

  ALTER TABLE test1 ADD COLUMN id INTEGER;
  CREATE SEQUENCE test_id_seq OWNED BY test1.id;
  ALTER TABLE test 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
  • 用从1到count(*)的序列填充它
  • 将其设置为主键/不为空

  • 这要归功于@resnyanskiy,他在评论中给出了这个答案。

    我来到这里是因为我也在寻找类似的东西。在我的例子中,我将数据从一组具有多个列的临时表复制到一个表中,同时将行ID分配给目标表。下面是我使用的上述方法的一个变体。 我在目标表的末尾添加了序列列。这样,我就不必在Insert语句中为它设置占位符。然后在目标表中简单地选择*自动填充此列。下面是我在PostgreSQL 9.6.4上使用的两条SQL语句

    ALTER TABLE target ADD COLUMN some_column SERIAL;
    INSERT INTO target SELECT * from source;
    

    要在v10中使用标识列

    ALTER TABLE test 
    ADD COLUMN id { int | bigint | smallint}
    GENERATED { BY DEFAULT | ALWAYS } AS IDENTITY PRIMARY KEY;
    
    有关标识列的说明,请参见

    有关“默认生成”和“始终生成”之间的差异,请参见


    有关更改序列的信息,请参见。

    我正在使用ORACLE,因此共享它可能对ORACLE中的ORACLE人员有用:ALTER TABLE TEST 1 ADD ID NUMBER;更新TEST1 SET ID=TEST1_SEQ.NEXTVAL;ALTER TABLE TEST1添加主键(ID);在执行UPDATE语句之前创建一个序列TEST1_SEQ进一步到@resnyanskiy的注释,这将在表中有数据时起作用。将填充ID并设置NOTNULL约束。完整的答案可以替换为评论中的一行。@EricWang谢谢,Eric,你是对的-我相信这在某些版本(几年前)不起作用,但我不确定。将答案转换为community-wiki。大型表格呢?这些语句是否锁定了很长时间?当使用
    ALTER TABLE ADD COLUMN id SERIAL PRIMARY KEY
    时,如何将
    id
    指定为
    bigint
    ?这应该标记为answer,并且答案应该属于@resnyanskiyI。必须先删除pkey,然后运行此命令<代码>改变表格放置约束此解决方案的问题是,如果表已包含行,则会出现错误:
    SQL错误[23502]:错误:列“id”包含空值
    @isapir:早期版本(第10页和第10.1页)中存在导致此错误的错误。它是用第10.2页固定的。这里的详细信息:谢谢@erwin brandstetter一年后,我再次找到了这个答案,bug显然已经修复,投票表决结果为上;)