9.16. 序列操作功能

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

表 9.47. 序列函数

FunctionReturn TypeDescription
currval(regclass)bigint对于指定序列,最近一次使用nextval返回的返回值
lastval()bigint对于任何序列,最近一次使用nextval返回的返回值
nextval(regclass)bigint提前序列并返回新值
setval(regclass, bigint)bigint设置序列的当前值
setval(regclass, bigint, boolean)bigint设置序列的当前值和is_called标志

序列函数要操作的序列由regclass参数指定,该参数只是pg_class系统目录中序列的 OID。但是,您不必手工查找 OID,因为regclass数据类型的 Importing 转换器将为您完成工作。只需编写用单引号引起来的序列名称,使其看起来像 Literals 常量。为了与普通 SQL 名称的处理兼容,除非字符串在序列名称周围包含双引号,否则它将转换为小写。从而:

nextval('foo')      operates on sequence foo
nextval('FOO')      operates on sequence foo
nextval('"Foo"')    operates on sequence Foo

序列名称可以根据需要使用模式限定:

nextval('myschema.foo')     operates on myschema.foo
nextval('"myschema".foo')   same as above
nextval('foo')              searches search path for foo

有关regclass的更多信息,请参见Section 8.19

Note

在 PostgreSQL 8.1 之前,序列函数的参数类型为text,而不是regclass,并且上述从文本字符串到 OID 值的转换将在每次调用期间在运行时发生。为了向后兼容,此功能仍然存在,但是在内部,现在在调用函数之前,将它作为从textregclass的隐式强制处理。

当您将序列函数的参数编写为未经修饰的 Literals 字符串时,它将成为regclass类型的常量。由于这实际上只是一个 OID,因此尽管稍后进行了重命名,模式重新分配等,它仍将跟踪最初标识的序列。对于列默认值和视图中的序列引用,通常需要这种“早期绑定”行为。但是有时您可能需要在运行时解析序列引用的“后期绑定”。要获得后期绑定行为,请强制将常量存储为text常量而不是regclass

nextval('foo'::text)      foo is looked up at runtime

请注意,后期绑定是 8.1 之前的 PostgreSQL 版本中唯一支持的行为,因此您可能需要执行此操作以保留旧应用程序的语义。

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

可用的序列函数是:

  • nextval

    • 将序列对象前进到下一个值,然后返回该值。这是原子完成的:即使多个会话同时执行nextval,每个会话也将安全地接收不同的序列值。

如果使用默认参数创建了序列对象,则连续nextval调用将返回以 1 开头的连续值。其他行为可以通过使用CREATE SEQUENCE命令中的特殊参数来获得;有关更多信息,请参见其命令参考页面。

Important

为了避免阻塞从相同序列中获取数字的并发事务,永远不会回滚nextval操作;也就是说,一旦获取了值,就将其视为已使用且不会再次返回。即使周围的事务稍后中止,或者调用查询最终不使用该值也是如此。例如,带有ON CONFLICT子句的INSERT将计算要插入的 Tuples,包括执行所有必需的nextval调用,然后再检测到任何可能导致其遵循ON CONFLICT规则的冲突。这样的情况将在分配值的序列中留下未使用的“漏洞”。因此,PostgreSQL 序列对象不能用于获取“无间隙”序列

此功能需要序列具有USAGEUPDATE特权。

  • currval

    • 返回nextval在当前会话中为此序列最近获取的值。 (如果从未在此会话中为此序列调用nextval,则会报告错误.)由于此方法返回的是会话本地值,因此它提供了一个可预测的答案,即自当前会话以来其他会话是否已执行nextval

此功能需要序列具有USAGESELECT特权。

  • lastval

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

此功能要求最后使用的序列具有USAGESELECT特权。

  • setval

    • 重置序列对象的计数器值。两参数形式将序列的last_value字段设置为指定值,并将其is_called字段设置为true,这意味着下一个nextval将在返回值之前使序列前进。 currval报告的值也设置为指定值。在三参数形式中,is_called可以设置为truefalsetrue与二参数形式的效果相同。如果将其设置为false,则下一个nextval将恰好返回指定值,并且序列前进从下一个nextval开始。此外,在这种情况下,由currval报告的值不会更改。例如,
SELECT setval('foo', 42);           Next nextval will return 43
SELECT setval('foo', 42, true);     Same as above
SELECT setval('foo', 42, false);    Next nextval will return 42

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

Important

由于序列是非事务性的,因此如果事务回滚,setval所做的更改不会被撤消。

此功能需要对序列具有UPDATE特权。