Fix ‘currval of sequence “…” is not yet defined in this session’ When Calling CURRVAL() in PostgreSQL

If you’re getting an error that reads something like ‘currval of sequence “sequence1” is not yet defined in this session‘ when calling the currval() function in PostgreSQL, it’s probably because nextval() hasn’t yet been called for that sequence in the current session.

If you want to avoid this error, only call the currval() function when you know that nextval() has been called against that sequence at least once in the current session.

Alternatively, you could call the lastval() function instead, which doesn’t report on any particular sequence – it reports on the last time nextval() was used in the current session, regardless of which sequence was used.

Example of Error

To demonstrate the error, let’s create a sequence:

CREATE SEQUENCE Sequence1;

Now let’s immediately call currval() against that sequence:

SELECT currval('Sequence1');

Result:

ERROR:  currval of sequence "sequence1" is not yet defined in this session

As expected, we get an error. If nextval() hasn’t been used against the specified sequence in the current session, there’ll be no value for currval().

Solution 1

The first solution is to ensure that nextval() has already been applied against the sequence at least once in the current session.

Example:

SELECT nextval('Sequence1');

Result:

1

Now that we’ve advanced the sequence in this session, we can go ahead and call currval() against it:

SELECT currval('Sequence1');

Result:

1

This time it returned the current value of the sequence without error.

Note that it’s the current session that’s relevant. Even if nextval() has been used against the sequence in a different session, we’ll still get the error if it hasn’t been used in the current session.

To demonstrate this, I’ll open a new session and call currval() against the sequence again:

SELECT currval('Sequence1');

Result:

ERROR:  currval of sequence "sequence1" is not yet defined in this session

As expected, I get an error again. Once again, we need to advance the sequence in this session before we can call currval() against it.

SELECT nextval('Sequence1');

Result:

2

Now the current value is 2. Let’s call currval() again:

SELECT currval('Sequence1');

Result:

2

This time the result is returned without an error.

For the sake of completeness, here’s what happens if I switch back to my original session and call currval() from there:

SELECT currval('Sequence1');

Result:

1

It’s back at 1. This is because currval() only reports on the sequence in the current session. It returns a session-local value, which gives a predictable answer whether or not other sessions have executed nextval() since the current session did.

Solution 2

Another way to deal with this issue is to call lastval() instead of currval(). Note that this function works differently, so it’s important to know the difference.

The lastval() function doesn’t report on any particular sequence – it reports on the last time nextval() was used in the current session, regardless of which sequence was used. It therefore doesn’t require the name of a sequence (it doesn’t require or accept any arguments).

Here’s what I get when running the function in my first session:

SELECT lastval();

Result:

1

And here it is in my second session:

SELECT lastval();

Result:

2

Obviously, this is no good if you’re only interested in a specific sequence, because it may return the result of a different sequence, but it’s still good to know that this function exists, and it may be useful in certain cases.