PostgreSQL下一个序列的值?

时间:2012-11-15 08:11:10

标签: codeigniter postgresql sequence postgresql-9.1 nextval

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

在添加新内容时,我想要内容的下一个ID。我尝试使用nextval()函数,但序列随之增加。如何在不使用nextval()函数的情况下获取序列的最后一个值?

或者有一种简单的方法可以做到这一点吗?

7 个答案:

答案 0 :(得分:34)

RETURNING

在现代的PostgreSQL(8.2或更高版本)中,您可以通过单次往返来执行此操作:

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

tbl_idserial列。 More in the manual

显式获取值

如果filename需要包含tbl_id(冗余),您仍然可以使用单个查询。
使用lastval()或更具体的currval()

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

The manual about lastval():

  

此功能与currval相同,不同之处在于取代   序列名称作为参数,它获取最后一个的值   nextval在当前会话中使用的序列。

如果你有(或可以)链接到表格的多个序列(即使是通过触发器或其他副作用),确定方式是使用currval('tbl_tbl_id_seq')

序列名称

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

tbl_tbl_id_seq是具有序列列tbl的表tbl_id的自动生成的默认值。但是没有保证。如果已定义,列默认值可以从任何序列中获取值。如果在创建表时采用默认名称,Postgres会根据硬编码算法选择下一个免费名称。

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

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

SQL Fiddle.

答案 1 :(得分:16)

使用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');

答案 2 :(得分:0)

即使这可以以某种方式完成,但这是一个可怕的想法,因为它可能会得到一个序列,然后被另一个记录使用!

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

答案 3 :(得分:0)

如果你不在一个会话中,你可以只使用nextval('you_sequence_name'),就可以了。

答案 4 :(得分:0)

要按字面意思回答你的问题,这里是如何获取序列的下一个值而不增加它:

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

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

答案 5 :(得分:0)

我试过这个并且效果很好

@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;

答案 6 :(得分:0)

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

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

希望它会有所帮助:)