选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

9.17. 序列操作函数 #

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

Table 9.50. 序列函数

函数

描述

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);     同上
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权限。


Caution

为了避免阻塞从相同序列获取数字的并发事务,nextval获得的值如果调用事务后续中止,就不会被重新使用。 这意味着事务中止或数据库崩溃可能导致分配值序列中的间隙。这也可能发生在没有事务中止的情况下。 例如,带有ON CONFLICT子句的INSERT将计算要插入的元组,包括执行任何必需的nextval调用, 然后才检测到可能导致其遵循ON CONFLICT规则的任何冲突。 因此,PostgreSQL序列对象不能用于获取无间隙序列

同样,setval函数所做的序列状态更改立即对其他事务可见, 并且如果调用事务回滚,则不会被撤消。

如果在包含nextvalsetval调用的事务提交之前, 数据库集簇崩溃,那么序列状态更改可能尚未传递到持久存储, 因此在集簇重新启动后,无法确定序列是保持其原始状态还是更新状态。 对于数据库内部使用序列而言,这是无害的,因为未提交事务的其他影响也不会可见。 但是,如果您希望将序列值用于持久性的数据库外部用途,请确保在这样做之前已经提交了nextval调用。

序列函数要操作的序列由一个regclass参数指定,该参数就是序列在pg_class系统目录中的 OID。不过,不必手动查找 OID,因为regclass数据类型的输入转换函数会替你完成这项工作。只需将序列名用单引号括起来,使其看上去像一个字面常量。为兼容普通SQL名称的处理方式,除非序列名被双引号括起,否则字符串会转换为小写。因此:

nextval('foo')      操作序列 foo
nextval('FOO')      操作序列 foo
nextval('"Foo"')    操作序列 Foo

必要时,序列名可以带模式限定:

nextval('myschema.foo')     操作 myschema.foo
nextval('"myschema".foo')   同上
nextval('foo')              在搜索路径中查找 foo

参见Section 8.19以获取更多有关以下类型的信息:regclass

Note

PostgreSQL 8.1 之前,序列函数的参数类型是 text,而不是 regclass;上述从文本字符串到 OID 值的转换会在每次调用时于运行期间执行。为保持向后兼容,这种能力仍然存在,但内部现在会在调用函数前,通过从 textregclass 的隐式强制转换来处理。

将序列函数的参数写成不加修饰的字符串字面量时,它会成为以下类型的常量:regclass。由于它实际上只是一个 OID,即使后来发生重命名、模式变更等情况,它仍会指向最初标识的序列。这种早绑定行为通常适用于列默认值和视图中的序列引用。但有时你可能希望采用后绑定,在运行时解析序列引用。要获得后期绑定行为,应强制将常量存储为text常量,而不是regclass

nextval('foo'::text)      foo运行时被查找

请注意,后期绑定是下列旧版本唯一支持的行为:PostgreSQL8.1 之前的版本,因此可能需要这样做来保留旧应用的语义。

当然,序列函数的参数既可以是常量,也可以是表达式。如果它是文本表达式,隐式强制转换就会导致运行时查找。