On this page
9.16. 序列操作功能
本节描述了对序列对象进行操作的函数,也称为序列生成器或仅称为序列。序列对象是使用CREATE SEQUENCE创建的特殊单行表。序列对象通常用于为表的行生成唯一的标识符。 Table 9.47中列出的序列函数提供了简单,多用户安全的方法,用于从序列对象中获取连续的序列值。
表 9.47. 序列函数
Function | Return Type | Description |
---|---|---|
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.18。
Note
在 PostgreSQL 8.1 之前,序列函数的参数类型为text
,而不是regclass
,并且上述从文本字符串到 OID 值的转换将在每次调用期间在运行时发生。为了向后兼容,此功能仍然存在,但是在内部,现在在调用函数之前,将它作为从text
到regclass
的隐式强制处理。
当您将序列函数的参数编写为未经修饰的 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 序列对象不能用于获取“无间隙”序列。
此功能需要序列具有USAGE
或UPDATE
特权。
currval
- 返回
nextval
在当前会话中为此序列最近获取的值。 (如果从未在此会话中为此序列调用nextval
,则会报告错误.)由于此方法返回的是会话本地值,因此它提供了一个可预测的答案,即自当前会话以来其他会话是否已执行nextval
。
- 返回
此功能需要序列具有USAGE
或SELECT
特权。
lastval
- 返回当前会话中
nextval
最近返回的值。此函数与currval
相同,不同之处在于,它不引用序列名称作为参数,而是引用当前会话中最近应用于序列nextval
的那个序列。如果当前会话中尚未调用nextval
,则调用lastval
是错误的。
- 返回当前会话中
此功能要求最后使用的序列具有USAGE
或SELECT
特权。
setval
- 重置序列对象的计数器值。两参数形式将序列的
last_value
字段设置为指定值,并将其is_called
字段设置为true
,这意味着下一个nextval
将在返回值之前使序列前进。currval
报告的值也设置为指定值。在三参数形式中,is_called
可以设置为true
或false
。true
与二参数形式的效果相同。如果将其设置为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
特权。