Sequences
The sequence is the schema object that generates a sequence of unique integers in ascending or descending order. The sequence is not associated with any table, but it can be used to populate data in the primary key or unique columns of a table. The PostgreSQL serial types are sequences.
Create a sequence
To create a sequence, use the CREATE SEQUENCE
command that defines a new sequence generator.
CREATE [ TEMPORARY | TEMP ] SEQUENCE [ IF NOT EXISTS ] <name>
[ AS <data_type> ]
[ INCREMENT [ BY ] <increment> ]
[ MINVALUE <minvalue> | NO MINVALUE ] [ MAXVALUE <maxvalue> | NO MAXVALUE ]
[ START [ WITH ] <start> ] [ CACHE <cache> ] [ [ NO ] CYCLE ]
[ OWNED BY { <table_name.column_name> | NONE } ]
TEMPORARY | TEMP |
If specified, the sequence object is created only for the current session. A temporary sequence is dropped at the end of the session. Existing permanent sequences with the same name are not visible in the current session while the temporary sequence exists. It is only possible to reference a permanent sequence with a schema-qualified name |
IF NOT EXISTS |
PostgreSQL creates a sequence if a relation with the same name does not exist. When this option is specified, PostgreSQL does not throw an error if a relation with the specified name is in the database. There is no guarantee that the existing relation matches the one that would be created |
<name> |
The name of the new sequence. Can be schema-qualified ( |
<data_type> |
The optional clause |
<increment> |
The optional clause |
MINVALUE <minvalue> | NO MINVALUE |
The optional clause |
MAXVALUE <maxvalue> | NO MAXVALUE |
The optional clause |
<start> |
The optional clause |
<cache> |
The optional clause |
[ NO ] CYCLE |
The If the optional |
OWNED BY table_name.column_name | NONE |
The |
The following example creates a sequence starting with 2
:
CREATE SEQUENCE mysequence START 2;
CREATE SEQUENCE
creates and initializes a new special single-row table with the specified name. The user who executes CREATE SEQUENCE
becomes the owner of the sequence.
If a schema name is given, the sequence is created in the specified schema. Otherwise, it is created in the current schema. Temporary sequences exist in a special schema, so a schema name cannot be given when creating a temporary sequence.
Sequences are based on bigint
arithmetic, the range cannot exceed the range of an eight-byte integer (from -9223372036854775808 to 9223372036854775807).
To examine the current state of a sequence, use SELECT
.
SELECT * FROM mysequence;
The result:
last_value | log_cnt | is_called ------------+---------+----------- 2 | 0 | f
The last_value
field of the sequence shows the last value allocated by any session. This value might be obsolete by the time it is printed if other sessions are actively doing nextval
calls.
PostgreSQL does not log (write to WAL) each fetching of a value from a sequence for performance reasons, it pre-logs a few fetches in advance. If PostgreSQL crashes, it loses (skips over) as many values as pre-logged. log_cnt
shows how many fetches remain before a new WAL record has to be written.
If the is_called
field is t
— true
, the next nextval
call will advance the sequence before returning a value. If is_called
is f
— false
, nextval
will return the last_value
value.
After a sequence is created, use the sequence manipulation functions to operate with the sequence. See Work with sequences.
CREATE SEQUENCE
conforms to the SQL standard, with the following exceptions:
-
You need to use the
nextval
function instead of the standardNEXT VALUE FOR
expression. -
The
OWNED BY
clause is a PostgreSQL extension.
Change a sequence
You can use ALTER SEQUENCE
to change the definition of a sequence generator. Any parameters that are not set in the ALTER SEQUENCE
command retain their previous settings.
You must own the sequence to use ALTER SEQUENCE
. To change a sequence’s schema, you must also have the CREATE
privilege on the new schema. To alter the owner, you must be a direct or indirect member of the new owning role, and that role must have CREATE
privilege on the sequence schema.
ALTER SEQUENCE [ IF EXISTS ] <name>
[ AS <data_type> ]
[ INCREMENT [ BY ] <increment> ]
[ MINVALUE <minvalue> | NO MINVALUE ] [ MAXVALUE <maxvalue> | NO MAXVALUE ]
[ START [ WITH ] <start> ]
[ RESTART [ [ WITH ] <restart> ] ]
[ CACHE <cache> ] [ [ NO ] CYCLE ]
[ OWNED BY { <table_name.column_name> | NONE } ]
ALTER SEQUENCE [ IF EXISTS ] <name> OWNER TO { <new_owner> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
ALTER SEQUENCE [ IF EXISTS ] <name> RENAME TO <new_name>
ALTER SEQUENCE [ IF EXISTS ] <name> SET SCHEMA <new_schema>
<name> |
The name of a sequence to be altered. Can be schema-qualified ( |
IF EXISTS |
When this option is specified, PostgreSQL does not throw an error if a sequence with the specified name does not exist in the database. A notification is displayed in this case |
<data_type> |
The optional clause |
<increment> |
The optional clause |
MINVALUE <minvalue> | NO MINVALUE |
The optional clause |
MAXVALUE <maxvalue> | NO MAXVALUE |
The optional clause |
<start> |
The optional clause |
<restart> |
The optional clause |
<cache> |
The optional clause |
[ NO ] CYCLE |
The If the optional |
OWNED BY <table_name.column_name> | NONE |
The |
<new_owner> |
The user name of the new sequence owner |
<new_name> |
The new name for the sequence |
<new_schema> |
The new schema for the sequence |
The following statement makes the mysequence
sequence descending from 10 to 2 using the step 2 and the cycle option:
ALTER SEQUENCE mysequence
INCREMENT -2
MINVALUE 2
MAXVALUE 10
RESTART 10
CYCLE;
ALTER SEQUENCE
does not immediately affect nextval
results in backends that have cached sequence values. They will only notice the changes after all cached values are used. The current server process responds to the changes immediately.
ALTER SEQUENCE
does not affect the currval
status for the sequence.
ALTER SEQUENCE
blocks concurrent nextval
, currval
, lastval
, and setval
calls.
For historical reasons, ALTER TABLE
can be used with sequences, but only with variants that are equivalent to the forms shown above.
Delete a sequence
The DROP SEQUENCE
command removes a sequence. It can only be dropped by its owner or a superuser.
DROP SEQUENCE [ IF EXISTS ] <name> [, ...] [ CASCADE | RESTRICT ]
IF EXISTS |
When this option is specified, PostgreSQL does not throw an error if a sequence with the specified name does not exist in the database. A notification is displayed in this case |
<name> [, …] |
The name of a sequence to be removed. Can be schema-qualified ( |
CASCADE |
Drop objects that depend on the sequence, and in turn all objects that depend on those objects. See Dependency Tracking |
RESTRICT |
Refuse to drop the sequence if any objects depend on it. This is the default behavior |
Example:
DROP SEQUENCE mysequence;
Work with sequences
The functions described below provide simple and multiuser-safe methods for obtaining successive values from sequence objects.
nextval
The nextval
function advances the sequence object to its next value and returns that value.
nextval ( regclass ) -> bigint
If multiple sessions execute nextval
concurrently, each safely receives a distinct sequence value. If the sequence object was created with default parameters, successive nextval
calls will return successive values beginning with 1
. Other behaviors can be specified by using appropriate parameters in the CREATE SEQUENCE command.
This function requires USAGE
or UPDATE
privilege on the sequence.
The example below shows how to create a sequence associated with a table column and fill the column using nextval
. To do this, perform the following steps:
-
Create a table.
CREATE TABLE book_orders ( order_id SERIAL, item_id INT NOT NULL, book_name VARCHAR NOT NULL, price NUMERIC NOT NULL, PRIMARY KEY(order_id, item_id) );
-
Create a new sequence associated with the
item_id
column of thebook_orders
table.CREATE SEQUENCE book_order_items START 1 OWNED BY book_orders.item_id;
-
Add rows to the table using the
nextval
function to fill theitem_id
column.INSERT INTO book_orders(order_id, item_id, book_name, price) VALUES (1, nextval('book_order_items'),'Hyperion',21), (1, nextval('book_order_items'),'War and Peace',26), (2, nextval('book_order_items'),'1984',20), (2, nextval('book_order_items'),'The Time Machine',19);
-
Check the table data.
SELECT * FROM book_orders;
The result:
order_id | item_id | book_name | price ----------+---------+------------------+------- 1 | 1 | Hyperion | 21 1 | 2 | War and Peace | 26 2 | 3 | 1984 | 20 2 | 4 | The Time Machine | 19
If you drop the book_orders
table, the book_order_items
sequence will also be dropped.
setval
The setval
function sets the current value of the sequence object, and optionally its is_called
flag. setval
can be called with two or three parameters.
setval ( regclass, bigint [, boolean ] ) -> bigint
Where:
-
regclass
is a sequence name; -
bigint
is thelast_value
value; -
boolean
is theis_called
value.
The form with two parameters sets the last_value
field to the specified value (bigint
) and sets its is_called
field to true
, meaning that the next nextval
call advances the sequence before returning a value. The currval
function will also return the specified value. In the form with three parameters, is_called
can be set to true
or false.
true
has the same effect as the two-parameter form. If is_called
is set to false
, the next nextval
call returns the specified value. The currval
function will also return this value. The table below lists the setval
examples and their results.
Command | Value returned by nextval |
---|---|
SELECT setval('mysequence', 14); |
15 |
SELECT setval('mysequence', 14, true); |
15 |
SELECT setval('mysequence', 14, false); |
14 |
The result returned by setval
is the second argument value.
The setval
function requires UPDATE
privilege on the sequence.
currval
The currval
function returns the value most recently obtained using nextval
for the specified sequence in the current session.
currval ( regclass ) -> bigint
If nextval
has never been called for this sequence in the current session, and you try to execute currval
, an error occurs. Since currval
returns a value for the current session, it gives a predictable result, regardless of whether nextval
is called in other sessions.
This function requires USAGE
or SELECT
privilege on the sequence.
Example:
SELECT currval('mysequence');
The result:
currval --------- 14 (1 row)
lastval
The function returns the value most recently obtained by nextval
in the current session for any sequence.
lastval () -> bigint
This function is identical to currval
, but instead of taking the sequence name as an argument, it refers to the most recent nextval
call related to any sequence in the current session. If nextval
has never been called in the current session, and you try to execute lastval
, an error occurs.
lastval
requires USAGE
or SELECT
privilege on the last used sequence.
Example:
SELECT * FROM lastval();
The result:
lastval --------- 14 (1 row)
List sequences in a database
You can retrieve information about sequences from the sequences view stored in the information_schema
schema.
SELECT sequence_schema, sequence_name, data_type, minimum_value, maximum_value, increment, cycle_option
FROM information_schema.sequences;
The result:
sequence_schema | sequence_name | data_type | minimum_value | maximum_value | increment | cycle_option -----------------+--------------------------+-----------+---------------+---------------------+-----------+-------------- public | mysequence | bigint | 2 | 10 | -2 | YES public | book_orders_order_id_seq | integer | 1 | 2147483647 | 1 | NO public | book_order_items | bigint | 1 | 9223372036854775807 | 1 | NO (3 rows)
The result includes the automatically generated book_orders_order_id_seq
sequence for the order_id
column of the serial type.
The pg_sequences view also provides access to useful information about each sequence in the database. For example, you can get information about sequence owners that information_schema.sequences
does not contain:
SELECT sequencename, sequenceowner FROM pg_sequences;
The result:
sequencename | sequenceowner --------------------------+--------------- mysequence | postgres book_orders_order_id_seq | postgres book_order_items | postgres
In addition, you can also fetch data from the pg_sequence and pg_class system catalogs using the following query:
SELECT pg_class.relname, pg_sequence.* FROM pg_sequence INNER JOIN pg_class ON pg_sequence.seqrelid = pg_class.oid;
The result:
relname |seqrelid|seqtypid|seqstart|seqincrement| seqmax |seqmin|seqcache| seqcycle ------------------------+--------+--------+--------+------------+-------------------+------+--------+---------- mysequence | 157170 | 20 | 2 | -2 | 10| 2 | 1 | t book_orders_order_id_seq| 160111 | 23 | 1 | 1 | 2147483647| 1 | 1 | f book_order_items | 160126 | 20 | 1 | 1 |9223372036854775807| 1 | 1 | f (3 rows)
It is also possible to use the \ds
psql meta-command to list sequences.
\ds
The result:
List of relations Schema | Name | Type | Owner --------+--------------------------+----------+---------- public | book_order_items | sequence | postgres public | book_orders_order_id_seq | sequence | postgres public | mysequence | sequence | postgres (3 rows)