PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

9.17. 序列操作函数 #

本节描述用于操作 序列对象 的函数, 序列对象也被称为序列生成器或简称序列。 序列对象是用 CREATE SEQUENCE 创建的特殊单行表。 序列对象通常被用来为一个表的行生成唯一标识符。 Table 9.55 中列出的序列函数, 提供了从序列对象获取相继序列值的简单的、 多用户安全的方法。

Table 9.55. 序列号函数

函数

说明

nextval ( regclass ) → bigint

把序列对象推进到它的下一个值并返回那个值。 这是原子性地完成的: 即使多个会话并发地执行 nextval, 每个会话也会安全地收到一个互不相同的序列值。 如果序列对象是用默认参数创建的, 相继的 nextval 调用将返回从 1 开始的相继值。 其他行为可以通过在 CREATE SEQUENCE 命令中使用适当的参数获得。

这个函数要求该序列上的 USAGE 或 UPDATE 特权。

setval ( regclass, bigint [, boolean ] ) → bigint

设置序列对象的当前值, 以及可选地设置它的 is_called 标志。 双参数形式把序列的 last_value 字段设置为指定的值, 并把它的 is_called 字段设置为 true, 意味着下一次 nextval 会在返回一个值之前推进该序列。 currval 将报告的值也被设置为指定的值。 在三参数形式中, is_called 可以被设置为 true 或 false。 true 具有与双参数形式相同的效果。 如果它被设置为 false, 下一次 nextval 将精确地返回指定的值, 而序列的推进则从其后的 nextval 开始。 此外, 在这种情况下 currval 报告的值不会被更改。 例如,

SELECT setval('myseq', 42);           Next nextval will return 43
SELECT setval('myseq', 42, true);     Same as above
SELECT setval('myseq', 42, false);    Next nextval will return 42

setval 返回的结果只是它的第二个参数的值。

这个函数要求该序列上的 UPDATE 特权。

currval ( regclass ) → bigint

返回当前会话中 nextval 为这个序列最近一次获得的值。 (如果本会话从未对这个序列调用过 nextval, 则会报告一个错误。) 由于它返回的是一个会话局部的值, 因此无论其他会话在当前会话执行之后是否执行过 nextval, 它都会给出一个可预测的答案。

这个函数要求该序列上的 USAGE 或 SELECT 特权。

lastval () → bigint

返回当前会话中 nextval 最近一次返回的值。 这个函数与 currval 相同, 只是它不把序列名作为参数, 而是引用当前会话中最近一次被应用了 nextval 的那个序列。 如果当前会话中还没有调用过 nextval, 那么调用 lastval 是一个错误。

这个函数要求最后使用的序列上的 USAGE 或 SELECT 特权。


Caution

为了避免阻塞从同一序列获取数字的并发事务, 如果调用事务后来中止了, nextval 获得的值不会被收回复用。 这意味着事务中止或数据库崩溃可能导致被赋值的序列出现空缺。 即使没有事务中止, 这种情况也可能发生。 例如,一条带有 ON CONFLICT 子句的 INSERT 会在检测到任何会令它遵循 ON CONFLICT 规则的冲突之前, 先计算出要被插入的元组, 包括执行所有需要的 nextval 调用。 因此, PostgreSQL 的序列对象 不能用来获得 “无空缺”的序列。

同样, 由 setval 做出的序列状态更改对其他事务立即可见, 并且在调用事务回滚时也不会被撤销。

如果数据库集群在提交一个包含 nextval 或 setval 调用的事务之前崩溃了, 序列的状态更改可能还没有到达持久存储, 因此不确定在集群重启之后序列将处于原始状态还是已更新状态。 这对序列在数据库内的使用是无害的, 因为未提交事务的其他效果同样不可见。 然而, 如果你想把一个序列值用于数据库之外的持久目的, 请确保 nextval 调用在此之前已被提交。

要由序列函数操作的序列由一个 regclass 参数指定, 它就是 pg_class 系统目录中该序列的 OID。 不过你不必手工查找这个 OID, 因为 regclass 数据类型的输入转换器会替你完成这项工作。 细节请参见 Section 8.19。