本节描述对sequence objects进行操作的函数,也称为序列生成器或序列。 序列对象是使用CREATE SEQUENCE创建的特殊单行表。 序列对象通常用于为表中的行生成惟一标识符。在Table 10.51中列出的序列函数,提供了简单的、多用户安全方法,用于从序列对象中获取连续的序列值。
Table 10.51. 序列函数
函数 描述 |
---|
将序列对象推进到下一个值并返回该值。这是自动完成的:即使多个会话并发地执行
这个函数需要 |
设置序列对象的当前值,以及可选的它的 SELECT setval('myseq', 42); Next
这个函数在序列上需要 |
返回
这个函数需要序列上的 |
返回
该函数在最后使用的序列上需要 |
为了避免阻塞从相同序列中获取数字的并发事务,nextval
操作永远不会回滚;也就是说,一旦获取了一个值,它就会被认为是已使用的,并且不会再次返回。
即使周围的事务随后中止,或者调用查询最终没有使用该值,也会出现这种情况。
例如,带有ON CONFLICT
子句的INSERT
将计算要插入的元组,包括执行任何必需的nextval
调用,在检测到任何可能导致它遵循ON CONFLICT
规则的冲突之前。
这种情况会在赋值序列中留下未使用的“holes”。因此,LightDB序列对象不能被用于获取 “gapless” 序列。
同样的,如果事务回滚,setval
所做的任何序列状态更改都不会撤消。
如果数据库群集在提交包含 nextval
或 setval
调用的事务之前崩溃,则序列状态更改可能尚未传递到持久存储,因此不确定序列在群集重新启动后是否具有其原始或更新的状态。对于在数据库内使用序列来说,这是无害的,因为未提交事务的其他影响也不会被看到。但是,如果您希望将序列值用于持久性的数据库外部用途,请确保在执行此操作之前已提交 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
关于regclass
的更多信息请参见Section 9.18。
在LightDB 8.1 之前,序列函数的参数类型是text
, 而不是 regclass
,并且前文所述的从文本串到 OID 值的转换将在每次调用的时候发生。
为了向后兼容,这个处理仍然存在,但是在内部实际上是通过在函数调用前隐式地将text
转换成regclass
实现的。
当你把一个序列函数的参数写成一个无修饰的文字串,那么它将变成类型为regclass
的常量。
因为这只是一个 OID,它将跟踪最初标识的序列,而不管后面是否改名、模式变化等等。
这种“早期绑定”的行为通常是列默认值和视图中引用的序列所需要的。
但是有时候你可能想要“延迟绑定”,其中序列的引用是在运行时解析的。
要得到延迟绑定的行为,我们可以强制常量被存储为text
常量,而不是regclass
:
nextval('foo'::text) foo
is looked up at runtime
当然,序列函数的参数也可以是表达式。如果它是一个文本表达式,那么隐式的转换将导致运行时的查找。