codeigniter PostgreSQL序列的下一个值?

am46iovg  于 2022-12-07  发布在  PostgreSQL
关注(0)|答案(8)|浏览(140)

我正在使用PostgreSQL来创建我的Codeigniter网站。我正在使用groxy crud来进行添加、编辑和删除操作。在进行编辑或添加时,我想根据内容的id动态地重命名上传的文件。我可以使用groxy crud的callback_after_upload函数来实现这一点。
我想在添加新内容时获得内容的下一个ID。我尝试使用nextval()函数,但序列会随之增加。如果不使用nextval()函数,如何获得序列的最后一个值?
或者有什么简单的方法可以做到这一点?

zlwx9yxi

zlwx9yxi1#

x1月0n1x日

只需 * 一次到数据库的往返 * 即可实现这一点:

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

tbl_id通常是serial or IDENTITY (Postgres 10 or later) column . More in the manual

显式提取值

如果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中找不到具有该名称的序列,则会引发异常。
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;

小提琴
古老的SQLFIDLE

vlurs2pr

vlurs2pr2#

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

ddarikpa3#

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

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

希望对你有帮助:)

ttisahbt

ttisahbt4#

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

bfhwhh0e

bfhwhh0e5#

为了从字面上回答您的问题,下面介绍了如何在不递增序列的情况下获取序列的下一个值:

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

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

kqhtkvqz

kqhtkvqz6#

2022年的答案
如果知道序列的名称,则可以使用pg_sequence_last_value()

SELECT pg_sequence_last_value('public.person_id_seq');
zfciruhq

zfciruhq7#

我试过这个,效果很好

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

x7yiwoj48#

即使这可以以某种方式做到这是一个可怕的想法,因为它将有可能得到一个序列,然后得到另一个记录使用!
更好的方法是保存记录,然后检索序列。

相关问题