当我使用此查询查看 PostgreSQL 13 表的当前主键种子时:
select CURRVAL(pg_get_serial_sequence('rss_sub_source', 'id'))
它告诉我:
SQL Error [55000]: ERROR: currval of sequence "rss_sub_source_id_seq" is not yet defined in this session
该id
列定义如下:
ALTER TABLE rss_sub_source
ALTER id SET NOT NULL, -- optional
ALTER id ADD GENERATED ALWAYS AS IDENTITY
(START WITH 1233);
表定义:
CREATE TABLE public.rss_sub_source (
id int8 NOT NULL GENERATED ALWAYS AS IDENTITY,
sub_url varchar NOT NULL,
created_time int8 NOT NULL DEFAULT date_part('epoch'::text, now()),
-- ... many more columns
CONSTRAINT rss_sub_source_pkey PRIMARY KEY (id),
CONSTRAINT unique_sub_url UNIQUE (sub_url)
);
如何查看当前主键的自增种子?
这些功能只有在同一个会话
currval(regclass)
中使用lastval()
后才 有意义nextval()
(不是事务!)。PostgreSQL 中的并发控制是这种行为背后的原因。如果您只是对序列的当前状态(不是会话中实际使用的最后一个序列号)感到好奇,您可以随时调用
nextval()
:返回下一个尚未使用的序列号。这带来了实际使用返回的 ID 的缺陷(这在适当的关系设计中应该无关紧要)。但是这种副作用是可以避免的。在 Postgres 中,
serial
列IDENTITY
是使用SEQUENCE
内部实现的,它恰好是一个类似表格的对象,可以像表格一样被查询。如果您对 a 的当前状态感到好奇SEQUENCE
,只需使用SELECT
:(需要序列的
SELECT
权限,而上面提到的序列函数需要USAGE
权限。)您需要知道序列的名称,并且您已经知道如何获取它:
pg_get_serial_sequence('rss_sub_source', 'id')
. 这也很容易猜到。看:对于临时使用,只需手动编译查询。或者你可以
\gexec
在 psql 中使用:看:
对于自动(或常规)使用,您需要动态 SQL 以将函数返回的文本值用作 SQL 标识符。这是一个简单的自定义函数来做到这一点。还考虑到
is_called
:称呼:
这对 SQLi 是安全的,因为
pg_get_serial_sequence()
根据需要返回安全双引号的标识符。该函数返回从此序列中消耗的最后一个值。(并不意味着它进入了表格。)下一个会更大。(假设默认序列为
INCREMENT
1!)它不使用序列号,也不需要
nextval()
在同一会话中调用过的序列号。考虑这个演示:
db<>fiddle here
通常你想要你刚刚生成的值序列值,或者导致生成,然后使用 lastval 是获取它的正确方法,但是你需要引发一个 nextval 调用来为 lastval 提供一个值。
如果由于某种原因您不需要知道该值。但只想要一些最近的值,可能来自另一个会话,甚至是回滚的事务。
select * from rss_sub_source_id_seq;
将在不推进序列的情况下为您提供有关序列当前状态的一些信息。
首先调用 nextval:
然后可以使用这个命令: