Autoincrement, but omit existing values in the column

前端 未结 3 1500
孤独总比滥情好
孤独总比滥情好 2021-01-24 11:46

I have a table:

create table DB.t1 (id  SERIAL,name varchar(255));

and insert some data:

insert into DB.t1 (name) values (\'nam         


        
相关标签:
3条回答
  • 2021-01-24 12:21

    @erwin-brandstetter Won't it be faster to first find the missing value and then simply setval('t1_id_seq'::regclass, ), thus removing excessive nextval calls? Also, if the question is how to make ids unique, assigning this code for default value won't solve the problem.

    I'd suggest using unique constraint or primary key constraint and handle unique violation exception.

    0 讨论(0)
  • 2021-01-24 12:33

    You can implement a trigger function on inserting. This function will chck if NEW.id is not null and update the sequence related to the id field.

    IF NEW.id IS NOT NULL THEN SELECT SETVAL(sequence_name_of_id_field,NEW.id);
    END IF;
    
    0 讨论(0)
  • 2021-01-24 12:43

    Update: Later, more detailed answer:

    • Make Postgres choose the next minimal available id

    This should work smoothly:

    CREATE OR REPLACE FUNCTION f_next_free(_seq regclass)
      RETURNS integer AS
    $func$
    BEGIN
       LOOP
          PERFORM nextval(_seq);
          EXIT WHEN NOT EXISTS (SELECT 1 FROM db.t1 WHERE id = lastval());
       END LOOP; 
    
       RETURN lastval();
    END
    $func$  LANGUAGE plpgsql VOLATILE;
    

    The loop is fetching the next number from the given sequence until one is found that is not yet in the table. Should even be safe for concurrent use, since we still rely on a sequence.

    Use this function in the column default of the serial column (replacing the default for the serial columns nextval('t1_id_seq'::regclass):

    ALTER TABLE db.t1 ALTER COLUMN id
    SET DEFAULT f_next_free('t1_id_seq'::regclass);
    

    The manual on lastval().

    This performs well with few islands and many gaps (which seems to be the case according to the example). To enforce uniqueness, add a unique constraint (or primary key) on the column.

    0 讨论(0)
提交回复
热议问题