如何在PostgreSQL中获取下一个序列值?

3

目前我在查找列的下一个序列值方面遇到了问题。

my_list表是通过以下方式创建的:

CREATE SEQUENCE my_list_id_seq;
CREATE TABLE IF NOT EXISTS
my_list (id int PRIMARY KEY UNIQUE NOT NULL DEFAULT nextval('my_list_id_seq'),
mycardno);
ALTER SEQUENCE my_list_id_seq OWNED BY my_list.id;

我尝试使用currval查询来查找下一个序列值(应该是1),但是我得到了

SELECT currval('my_list_id_seq');
ERROR:  currval of sequence "my_list_id_seq" is not yet defined in this session

如果我使用nextval查询,我将得到2,这不是我想要的,并且该序列将通过此查询增加1。
SELECT nextval('my_list_id_seq');

 nextval
---------
       2
(1 row)

在执行nextval查询之后,我现在可以使用currval查询。

SELECT currval('my_list_id_seq');

 currval
---------
       2
(1 row)

由于我在这个阶段找不到其他的解决方案,目前我的步骤是:

  1. 执行nextval并获取“下一个序列”值
  2. 使用ALTER SEQUENCE my_list_id_seq RESTART WITH "next sequence - 1";来设置序列值。 “next sequence - 1”是由C#(我使用WPF)完成的。

我想知道是否有直接的方法来解决这个问题。谢谢。


你已经得到了如何获取当前值的答案,但是你需要它做什么呢?你不能假设你获得的值在下一条记录插入之前不会增加。此外,如果事务失败,id列中可能会出现间隙,导致值甚至会增加。 - Steeeve
创建序列后,当您调用nextval()时,您将不会得到2,而是得到1。所以我真的不明白您的问题是什么。 - user330315
听起来你似乎从未需要过这个序列的值。试着解释一下你的目标,以及你的第二个表是什么样子的(简化描述)。请将这些细节放在你的问题中,而不是评论中。 - Steeeve
@testcb00,请您编辑您的问题并将所有解释添加到其中。 - user330315
这听起来像是一件奇怪的事情。特别是在并发访问的环境中,我觉得你不能依赖那个值。你用这种方法想解决的是什么潜在问题呢? - user330315
显示剩余3条评论
1个回答

5
根据文档,只有在会话中已调用nextval时,currval才有效:

返回当前会话中该序列最近一次由nextval获取的值。(如果在此会话中从未为此序列调用nextval,则报告错误。)

如果您想获取当前值,则可以尝试SELECT * FROM my_list_id_seq并使用last_value列中对应的值:

postgres=# CREATE SEQUENCE my_list_id_seq;
CREATE SEQUENCE
postgres=# CREATE TABLE IF NOT EXISTS
my_list (id int PRIMARY KEY UNIQUE NOT NULL DEFAULT nextval('my_list_id_seq'),
mycardno int);
CREATE TABLE
postgres=# ALTER SEQUENCE my_list_id_seq OWNED BY my_list.id;
ALTER SEQUENCE
postgres=# select * from my_list_id_seq;
 last_value | log_cnt | is_called 
------------+---------+-----------
          1 |       0 | f
(1 row)

从序列中选择会给你一个快照值,就像被错误命名/损坏的currval()一样。READ UNCOMMITTED或者WITH (NOLOCK)可以帮助,同样一个不撒谎的currval()实现也可以。目前来看,楼主的方法 - nextval()后跟ALTER SEQUENCE - 似乎是唯一能穿越事务/会话边界的选项,但当然需要额外的锁定... - DarthGizka
注意:看起来还是有一个可用的currval()函数,但它被称为pg_sequence_last_value(),并且没有文档记录。尽管如此,它的某些行为可能会很奇怪-请参阅https://www.postgresql.org/message-id/16018-e617465560d648c5%40postgresql.org - DarthGizka

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