Skip to content

9.17. 序列操作函数#

本节介绍用于操作序列对象(也称为序列生成器或序列)的函数。序列对象是使用CREATE SEQUENCE创建的特殊单行表。序列对象通常用于为表中的行生成唯一标识符。序列函数(列在表 9.52中)提供简单、多用户安全的方法,用于从序列对象获取连续的序列值。

表 9.52. 序列函数

函数

说明

nextval ( regclass ) → bigint

将序列对象推进到其下一个值并返回该值。这是原子操作:即使多个会话同时执行 nextval,每个会话都将安全地接收一个不同的序列值。如果序列对象已使用默认参数创建,则连续的 nextval 调用将返回从 1 开始的连续值。可以通过在 CREATE SEQUENCE 命令中使用适当的参数来获得其他行为。

此函数需要序列上的 USAGEUPDATE 权限。

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

设置序列对象的当前值,以及可选的 is_called 标志。双参数形式将序列的 last_value 字段设置为指定值,并将 is_called 字段设置为 true,这意味着下一个 nextval 将在返回一个值之前推进序列。 currval 报告的值也将设置为指定值。在三参数形式中, is_called 可以设置为 truefalsetrue 具有与双参数形式相同的效果。如果将其设置为 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,它都会给出可预测的答案。

此函数需要序列上的 USAGESELECT 权限。

lastval () → bigint

返回当前会话中最近由 nextval 返回的值。此函数与 currval 相同,只是它不将序列名称作为参数,而是引用当前会话中最近应用 nextval 的序列。如果在当前会话中尚未调用 nextval,则调用 lastval 是一个错误。

此函数需要对上次使用的序列的 USAGESELECT 权限。

注意

为了避免阻止从同一序列获取数字的并发事务,如果调用事务稍后中止,则不会回收通过nextval获取的值以供重新使用。这意味着事务中止或数据库崩溃会导致分配值序列中的间隙。即使没有事务中止,也会发生这种情况。例如,带有ON CONFLICT子句的INSERT将计算待插入元组,包括执行任何必需的nextval调用,然后再检测到任何冲突,从而导致它遵循ON CONFLICT规则。因此,PostgreSQL序列对象不能用于获取“无间隙”序列

同样,由setval做出的序列状态更改对于其他事务是立即可见的,并且如果调用事务回滚,则不会撤消这些更改。

如果在提交包含nextvalsetval调用的事务之前数据库集群崩溃,则序列状态更改可能尚未进入持久性存储,因此在集群重新启动后不确定序列将具有其原始状态还是更新状态。对于在数据库中使用序列来说这是无害的,因为未提交的事务的其他影响也不会可见。但是,如果您希望将序列值用于数据库外部的持久性目的,请确保在这样做之前已提交nextval调用。

由序列函数操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的 OID。但是,您不必手动查找 OID,因为regclass数据类型的输入转换器将为您完成这项工作。有关详细信息,请参见第 8.19 节