postgresqldatabase-designauto-incrementpostgresql-8.4

currval has not yet been defined this session, how to get multi-session sequences?


My objective is to get a primary key field automatically inserted when inserting new row in the table.

How to get a sequence going from session to session in PostgreSQL?

 doubleemploi@hanbei:/home/yves$ psql -d test
 Mot de passe : 
 psql (8.4.13)
 Saisissez « help » pour l''aide.

 test=> create sequence test001 start 10;
 CREATE SEQUENCE
 test=> select currval('test001');
 ERREUR:  la valeur courante (currval) de la séquence « test00 » n''est pas encore définie dans cette session
 --- current value not yet defined this session (???)
 test=> select setval('test001', 10);
 setval 
 --------
      10
 (1 ligne)

 test=> select currval('test00');
  currval 
 ---------
       10
 (1 ligne)

 test=> \q
 test@hanbei:/home/yves$ psql -d test
 Mot de passe : 
 psql (8.4.13)
 Saisissez « help » pour l''aide.

 test=> select currval('test001');
 ERREUR:  la valeur courante (currval) de la séquence « test00 » n''est pas encore définie dans cette session

Solution

  • This may be simpler than you think ...

    My objective is to get a primary key field automatically inserted when inserting new row in the table.

    Just set the default value of the column:

    ALTER TABLE tbl ALTER COLUMN tbl_id SET DEFAULT nextval('my_seq'::regclass);
    

    Or simpler yet, create the table with a serial type for primary key to begin with:

    CREATE TABLE tbl(
      tbl_id serial PRIMARY KEY
     ,col1 txt
      -- more columns
    );
    

    It creates a dedicated sequence and sets the default for tbl_id automatically.

    In Postgres 10 or later, consider an IDENTITY column instead. See:

    This way tbl_id is assigned the next value from the attached sequence automatically if you don't mention it in the INSERT. Works with any session, concurrent or not.

    INSERT INTO tbl(col1) VALUES ('foo');
    

    If you want the new tbl_id back to do something with it:

    INSERT INTO tbl(col1) VALUES ('foo') RETURNING tbl_id;