Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 
like image 399
MUY Belgium Avatar asked Sep 18 '12 16:09

MUY Belgium


People also ask

Is not yet defined in this session Currval?

CURRVAL is not yet defined in this session error occurs If you call the CURRVAL of a sequence that doesn't have a last value. The NEXTVAL of the sequence will be used to set the sequence's last value. The sequence CURRVAL returns the sequence's last value.

What value Currval holds Once you create a sequence?

The correct answer is c) Returns the last value across all nodes.

What is Currval in PostgreSQL?

currval(' sequence_name ') Returns the most recently returned value from nextval(' sequence_name '). This value is associated with a PostgreSQL session, and if the nextval() function has not yet been called in the connected session on the specified sequence sequence_name , there will be no "current" value returned.


2 Answers

The currval will return the last value generated for the sequence within the current session. So if another session generates a new value for the sequence you still can retrieve the last value generated by YOUR session, avoiding errors.

But, to get the last generated value on any sessions, you can use the above:

SELECT last_value FROM your_sequence_name; 

Be careful, if the value was used by other session with an uncommited (or aborted) transaction and you use this value as a reference, you may get an error. Even after getting this value it may already be out of date. Generally people just need the currval or even the return of setval.

like image 114
MatheusOl Avatar answered Oct 21 '22 05:10

MatheusOl


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:

  • Auto increment table column

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; 
like image 33
Erwin Brandstetter Avatar answered Oct 21 '22 05:10

Erwin Brandstetter