在 PostgreSQL 中,如果插入一行,则可以使用“nextval”来提前序列。

3

我正在有条件地向 PostgreSQL 表中插入一行,并手动指定 ID:

INSERT INTO foo (foo_id, foo_name)
SELECT 4, 'My Name'
WHERE NOT EXISTS (
    SELECT * FROM foo WHERE foo_id = 4
);

这不会增加生成下一个 foo_id 的序列。
如何仅在上述查询实际插入一行时运行 SELECT nextval('foo_foo_id_seq'::regclass);

你想让序列继续使用那个数字还是想根据当前值增加序列?(但在两种情况下,您都可能会在以后遇到唯一键冲突的问题) - user330315
继续使用该数字将有效。例如,在此情况下,如果插入一行,则希望序列的下一个值为 5。 - s16h
1个回答

2

您可以使用 setval() 提供新的序列值。

如果您想要改变序列以继续使用“强制”值,则可以在选择语句中使用 setval()

INSERT INTO foo (id, foo_name)
select *
from (
  VALUES (setval('foo_id_seq', 42), 'My Name')
) as t (id, foo_name)
WHERE NOT EXISTS (
    SELECT * FROM foo WHERE id = 42
);

如果插入一行,则序列将继续从43开始。

如果当前序列值已经大于43,那么如果其他事务插入表并依赖序列,这将在以后给你带来问题。


如果您想从当前值推进序列,请使用以下内容:

INSERT INTO foo (id, foo_name)
select id, foo_name
from (
  VALUES (42, 'My Name', nextval('foo_id_seq'))
) as t (id, foo_name, nextval)
WHERE NOT EXISTS (
    SELECT * FROM foo WHERE id = 42
);

嗯,那样做有点可行,但我很想确保“我的名字”ID为1(在我的情况下,它实际上不是1-因此它不一定是表中发生的第一个插入)。 - s16h
@s16h:你为什么需要那个?你不应该依赖于特定的ID值。 - user330315
我理解并同意您的意见。但是,在这种情况下,我需要这样做。 - s16h
关于插入语句,你说得完全正确,我不知道为什么会那样输入。我已经编辑过来反映实际情况了。 - s16h
这对我的使用情况来说已经足够好了,完美!非常感谢。 - s16h

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