In PostgreSQL, the nextval()
function is used to advance sequence objects to their next value and return that value. We pass the name of the sequence when we call the function. This assumes that the sequence object exists.
Syntax
The syntax goes like this:
nextval ( regclass )
Here, regclass
is the sequence’s OID in the pg_class
system catalog view. However, we can pass either the name of the sequence or its OID. If we pass the name, Postgres converts it into its OID for us.
Example
Let’s create a sequence:
CREATE SEQUENCE Sequence1;
Now let’s use nextval()
to advance the sequence to its next value and return the result:
SELECT nextval('Sequence1');
Result:
1
In this case, I passed the sequence’s name, and Postgres converted it into the OID for me. When I created the sequence I used the default settings, and so when I called nextval()
for the first time it returned 1
.
Let’s call nextval()
some more:
SELECT
nextval('Sequence1'),
nextval('Sequence1'),
nextval('Sequence1'),
nextval('Sequence1');
Result:
nextval | nextval | nextval | nextval ---------+---------+---------+--------- 2 | 3 | 4 | 5
We can see that it advanced to the next value each time it was called.
Use the OID
We can alternatively use the sequence’s OID:
SELECT nextval(50355);
Result:
nextval --------- 6
Technically, the argument passed to the nextval()
function is actually its OID from the pg_class
system catalog view. When we pass the sequence’s name, Postgres looks up its OID and uses that. The regclass
data type’s input converter does it all for us, so we can pass the name without needing to run joins across multiple tables to find its OID.
Use nextval()
When Inserting Data
We can use the nextval()
function when inserting data into a table. This allows us to have a column that contains sequential values across all rows.
Let’s create a table, then use an INSERT
statement with the nextval()
function:
CREATE TABLE idiots (
IdiotId integer NOT NULL PRIMARY KEY,
IdiotName VARCHAR
);
INSERT INTO Idiots ( IdiotId, IdiotName )
VALUES
( nextval('Sequence1'), 'Dumb' ),
( nextval('Sequence1'), 'Dumber' ),
( nextval('Sequence1'), 'Dumbest' )
RETURNING *;
Result:
idiotid | idiotname ---------+----------- 6 | Dumb 7 | Dumber 8 | Dumbest
Here, we inserted three rows into the table, and used the nextval()
function to populate the IdiotId
column.
Apply nextval()
to the Column Definition
We can take the previous example a step further and apply the nextval()
function to the actual column definition when we create the table. This will eliminate the need to use nextval()
every time we insert a new row.
Example:
DROP TABLE IF EXISTS Idiots;
CREATE SEQUENCE idiots_idiotid_seq AS integer;
CREATE TABLE idiots (
IdiotId integer NOT NULL DEFAULT nextval('idiots_idiotid_seq'),
IdiotName VARCHAR
);
ALTER SEQUENCE idiots_idiotid_seq OWNED BY Idiots.IdiotId;
Here, we created a new sequence, applied it to the table definition via nextval()
, and then altered the sequence so that it’s owned by the column.
Now we can insert new rows without having to call nextval()
within our INSERT
statement:
INSERT INTO Idiots ( IdiotName )
VALUES
( 'Dumb' ),
( 'Dumber' ),
( 'Dumbest' )
RETURNING *;
Result:
idiotid | idiotname ---------+----------- 1 | Dumb 2 | Dumber 3 | Dumbest