获取当前(在运行查询的时刻)序列值的选项

107
如何在PostgreSQL 8.4中获取当前序列值?
注意:我需要这个值用于某种统计,只需检索并存储。手动递增的并发和竞争条件与问题无关。
注意2:该序列在多个表之间共享。
注意3:currval不起作用,因为:
返回当前会话中此序列最近获得的nextval的值
ERROR: 在此会话中尚未定义序列“”的currval
我的当前想法:解析DDL,这很奇怪

你知道这个序列的名称吗?你需要担心多个会话同时使用该序列吗? - mu is too short
@mu 太短了:是的,序列名称已知。我需要的是在代码运行时实际的值。 - zerkms
你可能正在寻找Bohemian的更新说明中提到的currval - mu is too short
@mu太短了: 如果那么容易就好了 :-) "在当前会话中返回由nextval获取的此序列最新值" - zerkms
1
尝试执行 select * from sequencename; - Scott Marlowe
3个回答

216

您可以使用:

SELECT last_value FROM sequence_name;

更新:这在CREATE SEQUENCE语句中有记录:

虽然您不能直接更新序列,但可以使用查询:

SELECT * FROM name;

来检查序列的参数和当前状态。特别是,序列的last_value字段显示了任何会话分配的最后一个值。(当然,如果其他会话正在积极地进行nextval调用,则该值可能已经过时。)


就是这样!请您还能否附上一份文档的参考,解释了我们可以用这种方式使用序列,然后我会检查一下。 - zerkms
1
你如何找到你的序列名称? - undefined

15

如果该序列用于表中的唯一标识符,您可以简单地执行以下操作:

select max(id) from mytable;

最高效的方法,虽然是针对Postgres特定的:

select currval('mysequence');

虽然技术上这会返回通过调用nextval('mysequence')生成的最后一个值,但这个值可能不会被调用者所使用(如果未使用,则会在自增ID列中留下间隙)。


7
max(id) 不能保证接近序列值。顺便提一下,该序列在多个表之间共享。抱歉忘记提到这一点。 - zerkms
27
currval无法使用 - 因为它返回的是当前会话中最新的值。我根本没有在当前会话中调用nextval,所以会出现“ERROR:序列"<sequence name>"的currval在此会话中尚未定义”的错误提示。 - zerkms

12
某个时间点开始,一个秘密函数(即未记录 ... 仍然存在)确切地执行以下操作: SELECT pg_sequence_last_value('schema.your_sequence_name'); 更新:事实证明,这个函数并不完全适用于生产环境。函数名字有误导性 - 它不是最后一个发行的值,而是最后一个保存/缓存到磁盘上的值。这意味着它可能显示比实际值更高的数字。

1
为什么要使用未记录的函数,如果有记录的 SELECT last_value FROM sequence_name; 呢? - zerkms
1
我不能说原作者为什么编写了这个函数,但我可以说它是一项小型便利功能,在某些情况下很受欢迎,比如在函数中使用或在单个查询中比较其随时间变化。当然,“FROM”版本也可以做到所有这些。 - Alexi Theodore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接