序列操作函数 =============== 本节描述用于操作 *序列对象* 的 OushuDB 的函数。序列对象(也叫序列生成器或只是序列)是用CREATE SEQUENCE 创建的特殊的单列表。一个序列对象通常用于生成表中行的唯一标识。序列函数(如下表所列)提供了从序列对象中获取连续序列值的简单的,多用户安全的方法。 **表.序列函数** .. list-table:: :widths: auto :header-rows: 1 * - 函数 - 返回类型 - 描述 * - nextval(regclass) - bigint - 递增序列并返回新值 * - setval(regclass, bigint) - bigint - 设置序列的当前数值 * - setval(regclass, bigint, boolean) - bigint - 设置序列的当前数值以及is_called标志 被序列函数操作的序列是用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 参阅 `对象标识符类型 <./object-identifier-types.html>`_ 获取有关regclass的更多信息。 .. note:: 如果你把一个序列函数的参数写成一个无修饰的文本字符串,那么它将变成类型为regclass 的常量。因为这只是一个 OID ,它将跟踪最初标识的序列,而不管后面是否改名、模式是否变化等等。这种"提前绑定"的行为通常是字段缺省和视图里面引用序列所需要的。但是有时候你可能想要"推迟绑定",这个时候序列的引用是在运行时解析的。 要获取推迟绑定的行为,我们可以强制存储为text常量,而不是regclass常量: :: nextval('foo'::text) foo 在运行时查找 当然,序列函数的参数也可以是表达式。如果它是一个文本表达式,那么隐含的转换将导致运行时的查找。 可用的序列函数有: nextval 递增序列对象到它的下一个数值并且返回该值。这个动作是自动完成的: 即使多个会话并发运行nextval,每个进程也会安全地收到一个唯一的序列值。 setval 重置序列对象的计数器数值。2个参数的形式设置序列的last_value 字段为声明数值并且将其is_called字段设置为true,表示下一次nextval将在返回数值之前递增该序列。在3个参数形式里is_called可以设置为true 或false。如果你把它设置为false,那么下一次nextval 将返回这里声明的数值而随后nextval才开始递增该序列。例如: :: SELECT setval('foo', 42); 下次nextval将返回43 SELECT setval('foo', 42, true); 和上面一样 SELECT setval('foo', 42, false); 下次nextval将返回42 setval返回的结果就是它的第二个参数的数值。 如果一个序列对象是带着缺省参数创建的,那么对它连续调用nextval 将返回从1开始的后续的数值。其他的行为可以通过使用CREATE SEQUENCE 命令里的特殊参数获取。 **重要:** 为了避免从同一个序列获取数值的当前事务被阻塞,nextval 操作决不会回滚;也就是说,一旦一个数值已经被抓走,那么就认为它已经用过了, 即使调用nextval的事务后面又退出了也一样。 这就意味着退出的事务可能在序列赋予的数值中留下未使用的"空洞"。setval 操作也从不回滚。