Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find out if a sequence was initialized in this session?

I need to read the current value of a sequence in a function. However, for the first time in each session I try to use currval(), I get following error:

currval of sequence "foo_seq" is not yet defined in this session

Hint for those who might find this question by googling for this error: you need to initialize the sequence for each session, either by nextval() or setval().

I could use something like lastval() or even setval('your_table_id_seq', (SELECT MAX(id) FROM your_table)); instead, but this seems seems either prone to gaps or slower than simple currval(). My aim is to avoid gaps and inconsistencies (I know some of the values will be added manually), so using nextval() before logic handling them is not ideal for my purpose. I would need this to initialize the sequence for the session anyway, but I would prefer to do something like this:

--start of the function here
IF is_not_initialized THEN
  SELECT setval('foo_seq', (SELECT MAX(id) FROM bar_table)) INTO _current;
ELSE
  SELECT currval('foo_seq') INTO _current;
END IF; 
--some magic with the _current variable and nextvalue() on the right position

The point is that I have no idea how might "is_not_initialized" look like and whether is it possible at all. Is there any function or other trick to do it?

EDIT: Actually, my plan is to let each group of customers choose between proper sequence, no sequence at all, and the strange "something like a sequence" I'm asking for now. Even if the customer wanted such a strange sequence, it would be used only for the columns where it is needed - usually because there are some analog data and we need to store their keys (usually almost gapless sequence) into the DB for backward compatibility.

Anyway, you are right that this is hardly proper solution and that no sequence might be better than such a messy workaround in those situations, so I'll think (and discuss with customers) again whether it is really needed.

like image 409
Pavel V. Avatar asked Jun 12 '14 10:06

Pavel V.


People also ask

How do I find the sequence number in PostgreSQL?

CREATE SEQUENCE creates a new sequence number generator. This involves creating and initializing a new special single-row table with the name name . The generator will be owned by the user issuing the command. If a schema name is given then the sequence is created in the specified schema.

How do I use 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.

Is not yet defined in this session sequence?

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 is Nextval in Postgres?

NEXTVAL is a function to get the next value from a sequence. Sequence is an object which returns ever-increasing numbers, different for each call, regardless of transactions etc. Each time you call NEXTVAL , you get a different number. This is mainly used to generate surrogate primary keys for you tables.

What is the difference between initial initialization and initial sequence number?

Initialization values are called initial sequence numbers. As per TCP specification, the initial value needs not to be zero (it may be any random number). SYN is the first TCP segment from the client to the server in a three-way handshake, for the connection setup procedure.

How do you find a term in a sequence?

For finding a term in a sequence there are two ways to determine, Recursive way/formula for determining a term (say rth term) in a sequence here, a r is the r th term in a sequence. a r-1 is the (r-1) th term in a sequence and d is a common difference.

What is initial sequence Number (ISN) in TCP?

Initial sequence number (ISN) in TCP : TCP initialize sequence number counters at the time of TCP connection establishment. Initialization values are called initial sequence numbers. As per TCP specification, the initial value needs not to be zero (it may be any random number).

What is a sequence of numbers called?

A Sequence is a set of things (usually numbers) that are in order. Each number in the sequence is called a term (or sometimes "element" or "member"), read Sequences and Series for a more in-depth discussion. Finding Missing Numbers. To find a missing number, first find a Rule behind the Sequence.


1 Answers

Craig, a_horse and pozs have provided information which can help you understand principles of using sequences. Apart from the question how are you going to use it, here is a function which returns current value of a sequence if it has been initialized or null otherwise.

If a sequence seq has not been initialized yet, currval(seq) raises exception with sqlstate 55000.

create or replace function current_seq_value(seq regclass)
returns integer language plpgsql 
as $$
begin
    begin
        return (select currval(seq));
    exception
        when sqlstate '55000' then return null;
    end;
end $$;

select current_seq_value('my_table_id_seq')
like image 190
klin Avatar answered Sep 27 '22 23:09

klin