n1000
n1000

Reputation: 5314

How to fill a nullable integer column and convert it into a serial primary key in Postgresql?

My table contains an integer column (gid) which is nullable:

 gid | value
-------------
  0  |   a
     |   b
  1  |   c
  2  |   d
     |   e

Now I would like to change the gid column into a SERIAL primary key column. That means filling up the empty slots with new integers. The existing integers must remain in place. So the result should look like:

 gid | value
-------------
  0  |   a
  3  |   b
  1  |   c
  2  |   d
  4  |   e

I just can't figure out the right SQL command for doing the transformation. Code sample would be appreciated...

Upvotes: 0

Views: 637

Answers (1)

user330315
user330315

Reputation:

A serial is "just" a column that takes it default value from a sequence. Assuming your table is named n1000 then the following will do what you want.

The first thing you need to do is to create that sequence:

create sequence n1000_gid_seq;

Then you need to make that the "default" for the column:

alter table n1000 alter column gid set default nextval('n1000_gid_seq');

To truly create a "serial" you also need to tell the sequence that it is associated with the column:

alter sequence n1000_gid_seq owned by n1000.gid;

Then you need to advance the sequence so that the next value doesn't collide with the existing values:

select setval('n1000_gid_seq', (select max(gid) from n1000), true);

And finally you need to update the missing values in the table:

update n1000 
  set gid = nextval('n1000_gid_seq')
where gid is null;

Once this is done, you can define the column as the PK:

alter table n1000 
   add constraint pk_n1000
   primary key (gid);

And of course if you have turned off autocommit you need to commit all this.

Upvotes: 8

Related Questions