PostgreSQL下一个值的序列



我的Codeigner网站使用PostgreSQL。我正在使用杂货店crud进行添加、编辑和删除操作。在进行编辑或添加时,我想根据内容的id动态重命名上传的文件。我可以使用杂货店crud的callback_after_upload函数来实现这一点。

添加新内容时,我想要内容的下一个id。我尝试使用nextval()函数,但序列会随之递增。如果不使用nextval()函数,如何获得序列的最后一个值?

或者有没有一个简单的方法我可以做到这一点?

RETURNING

对于到数据库的单个往返,这是可能的:

INSERT INTO tbl(filename)
VALUES ('my_filename')
RETURNING tbl_id;

tbl_id通常是serialIDENTITY(Postgres 10或更高版本)列。手册中有更多内容。

显式获取值

如果filename需要(冗余地)包括tbl_id,则仍然可以使用单个查询。

使用lastval()或更具体的currval()

INSERT INTO tbl (filename)
VALUES ('my_filename' || currval('tbl_tbl_id_seq')   -- or lastval()
RETURNING tbl_id;

参见:

  • 在同一INSERT期间另一列中的串行列的引用值

如果在这个过程中可能会推进多个序列(即使是通过触发或其他副作用),肯定的方法是使用currval('tbl_tbl_id_seq')

序列名称

在我的示例中,字符串文字'tbl_tbl_id_seq'应该是序列的实际名称,并强制转换为regclass,如果在当前search_path中找不到该名称的序列,则会引发异常。

CCD_ 16是为具有串行列CCD_ 18的表CCD_ 17自动生成的默认值。但没有任何保证。列默认值可以从任何序列中获取值(如果已定义)。如果在创建表时使用默认名称,Postgres会根据一个简单的算法选择下一个可用名称。

如果您不知道serial列的序列名称,请使用专用函数pg_get_serial_sequence()。可以在飞行中完成:

INSERT INTO tbl (filename)
VALUES ('my_filename' || currval(pg_get_serial_sequence('tbl', 'tbl_id'))
RETURNING tbl_id;

db<gt;fiddle此处
旧sqlfiddle

使用currval()函数访问先前获得的序列值。

但只有当nextval()在之前被调用时,它才会返回一个值。

在没有实际获得序列的下一个值的情况下,绝对没有办法"窥探"它

但你的问题还不清楚。如果在执行插入之前调用nextval(),则可以在插入中使用该值。或者更好的是,在插入语句中使用currval()

select nextval('my_sequence') ...
... do some stuff with the obtained value
insert into my_table(id, filename)
values (currval('my_sequence'), 'some_valid_filename');

我偶然发现了这个问题b/c我正试图按表查找下一个序列值。这并没有回答我的问题,但这是如何完成的,它可能会帮助那些不按名称而是按表查找序列值的人:

SELECT nextval(pg_get_serial_sequence('<your_table>', 'id')) AS new_id; 

希望有帮助:)

2022年答案

如果您知道序列的名称:,则可以使用pg_sequence_last_value()

SELECT pg_sequence_last_value('public.person_id_seq');

如果你不在会话中,你可以直接nextval('you_sequence_name'),这很好。

要从字面上回答您的问题,以下是如何在不递增的情况下获得序列的下一个值:

SELECT
CASE WHEN is_called THEN
last_value + 1
ELSE
last_value
END
FROM sequence_name

显然,在实践中使用此代码不是一个好主意不能保证下一行真的会有这个ID。但是,出于调试目的,在不递增序列的情况下知道序列的值可能会很有趣,这就是你可以做到的。

我试过了,它非常适合

@Entity
public class Shipwreck {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq")
@Basic(optional = false)
@SequenceGenerator(name = "seq", sequenceName = "shipwreck_seq", allocationSize = 1)
Long id;

CREATE SEQUENCE public.shipwreck_seq
INCREMENT 1
START 110
MINVALUE 1
MAXVALUE 9223372036854775807
CACHE 1;

即使可以以某种方式做到这一点,这也是一个可怕的想法,因为有可能得到一个序列,然后被另一个记录使用!

一个更好的想法是保存记录,然后检索序列。

相关内容

  • 没有找到相关文章

最新更新