跳到主要内容

CREATE SEQUENCE 语句

CREATE SEQUENCE 语句用于创建一个新的序列号生成器。

示例

生成一个从 1 开始递增的序列:

CREATE SEQUENCE serial;

从指定起始值生成序列:

CREATE SEQUENCE serial START 101;

使用 INCREMENT BY 生成奇数序列:

CREATE SEQUENCE serial START WITH 1 INCREMENT BY 2;

生成一个从 99 开始递减的序列:

CREATE SEQUENCE serial START WITH 99 INCREMENT BY -1 MAXVALUE 99;

默认情况下不允许循环,到达边界后会报错,例如:

Sequence Error:
nextval: reached maximum value of sequence "serial" (10)
CREATE SEQUENCE serial START WITH 1 MAXVALUE 10;

CYCLE 允许在同一序列中循环取值:

CREATE SEQUENCE serial START WITH 1 MAXVALUE 10 CYCLE;

创建与删除序列

序列可以像其他目录对象一样被创建和删除。

覆盖已存在的序列:

CREATE OR REPLACE SEQUENCE serial;

仅当序列不存在时才创建:

CREATE SEQUENCE IF NOT EXISTS serial;

删除序列:

DROP SEQUENCE serial;

如果序列存在则删除:

DROP SEQUENCE IF EXISTS serial;

将序列用于主键

序列可在 CREATE TABLE 语句 中作为 DEFAULT 值使用。

下面的示例使用序列生成整数主键

CREATE SEQUENCE id_sequence START 1;
CREATE TABLE tbl (id INTEGER PRIMARY KEY DEFAULT nextval('id_sequence'), s VARCHAR);
INSERT INTO tbl (s) VALUES ('hello'), ('world');
SELECT * FROM tbl;

该脚本会得到如下表:

ids
1hello
2world

也可以通过 ALTER TABLE 语句 添加序列。下面的示例添加了 id 列,并用序列生成的值填充该列:

CREATE TABLE tbl (s VARCHAR);
INSERT INTO tbl VALUES ('hello'), ('world');
CREATE SEQUENCE id_sequence START 1;
ALTER TABLE tbl ADD COLUMN id INTEGER DEFAULT nextval('id_sequence');
SELECT * FROM tbl;

该脚本会得到与前一个示例相同的结果表。

获取下一个值

要从序列中获取下一个值,请使用 nextval

CREATE SEQUENCE serial START 1;
SELECT nextval('serial') AS nextval;
nextval
1

INSERT 命令中使用该序列:

INSERT INTO distributors VALUES (nextval('serial'), 'nothing');

获取当前值

你也可以查看序列的当前值。请注意,在调用 currval 前必须先调用过 nextval,否则会抛出序列化错误(sequence is not yet defined in this session)。

CREATE SEQUENCE serial START 1;
SELECT nextval('serial') AS nextval;
SELECT currval('serial') AS currval;
currval
1

语法

CREATE SEQUENCE 会创建一个新的序列号生成器。

如果提供了 schema 名称,则序列会在指定 schema 中创建;否则会在当前 schema 中创建。临时序列存在于特殊 schema 中,因此创建临时序列时不能指定 schema 名称。序列名必须与同一 schema 中其他序列的名称不同。

序列创建后,可使用 nextval 函数对其进行操作。

参数

名称描述
CYCLE or NO CYCLECYCLE 选项允许序列在递增序列达到 maxvalue 或递减序列达到 minvalue 后回绕。达到边界后,下一个生成值分别为 minvaluemaxvalue。如果指定 NO CYCLE,序列达到最大值后再调用 nextval 将返回错误。若未指定 CYCLENO CYCLE,默认是 NO CYCLE
increment可选子句 INCREMENT BY increment 指定在当前序列值上增加的步长以生成新值。正值表示递增序列,负值表示递减序列。默认值为 1。
maxvalue可选子句 MAXVALUE maxvalue 用于确定序列的最大值。如果未提供该子句或指定 NO MAXVALUE,将使用默认值。递增序列和递减序列的默认值分别为 2^63 - 1 和 -1。
minvalue可选子句 MINVALUE minvalue 用于确定序列可生成的最小值。如果未提供该子句或指定 NO MINVALUE,将使用默认值。递增序列和递减序列的默认值分别为 1 和 -(2^63 - 1)。
name要创建的序列名称(可选 schema 限定)。
start可选子句 START WITH start 允许序列从任意值开始。递增序列的默认起始值为 minvalue,递减序列的默认起始值为 maxvalue
TEMPORARY or TEMP指定后,序列对象仅在当前会话中创建,并在会话退出时自动删除。临时序列存在期间(在当前会话中),同名的永久序列不可见,除非通过带 schema 的名称引用。

序列基于 BIGINT 算术,因此其取值范围不能超过 8 字节整数范围(-9223372036854775808 到 9223372036854775807)。

限制

由于 Goose 依赖管理器的限制,DROP SEQUENCE 在某些边缘场景下会失败。 例如,删除一个使用序列的列后,理论上应允许删除该序列,但目前仍会报错:

CREATE SEQUENCE id_sequence START 1;
CREATE TABLE tbl (id INTEGER DEFAULT nextval('id_sequence'), s VARCHAR);

ALTER TABLE tbl DROP COLUMN id;
DROP SEQUENCE id_sequence;
Dependency Error:
Cannot drop entry "id_sequence" because there are entries that depend on it.
table "tbl" depends on index "id_sequence".
Use DROP...CASCADE to drop all dependents.

可以通过使用 CASCADE 修饰符来规避该问题。 以下命令可删除该序列:

DROP SEQUENCE id_sequence CASCADE;