问题: 我需要做这样的事情
drop table if exists tt_t;
create temp table tt_t(id serial primary key, main_id int, external_id int);
insert into tt_t(main_id, external_id)
select currval(pg_get_serial_sequence('tt_t', 'id')), 1
where not exists (select from tt_t where external_id = 1);
但是执行会引发错误
SQL错误[55000]:错误:在此会话中尚未定义序列“ tt_t_id_seq”的当前时间
解决方案: 有一种方法可以用匿名代码块来解决这个问题
do
$$
begin
if not exists(select from tt_t where external_id = 1)
then
insert into tt_t(external_id, main_id)
values(1, currval(pg_get_serial_sequence('tt_t', 'id')));
end if;
end;
$$
;
如何在没有匿名代码块(UPD:并且没有任何DDL更改)的情况下进行修复?
答案 0 :(得分:1)
可能的解决方案:
insert into tt_t(id, main_id, external_id)
select nextval(pg_get_serial_sequence('tt_t', 'id')), currval(pg_get_serial_sequence('tt_t', 'id')), 1
where not exists (select from tt_t where external_id = 1);
已经向我提出了较短的代码
insert into tt_t(id, main_id, external_id)
select nextval(pg_get_serial_sequence('tt_t', 'id')), lastval(), 1
where not exists (select from tt_t where external_id = 1);
但是我不确定是否将首先计算nextval
答案 1 :(得分:1)
使用默认值怎么办?
drop table if exists tt_t;
create temp table tt_t(id serial primary key, main_id int default lastval(), external_id int);
insert into tt_t(external_id)
select 1
where not exists (select * from tt_t where external_id = 1);
理论上,不可能在nextval()
和id
的那个之间调用另一个lastval()
。但是我不确定100%是否有一些我不知道的极端情况。
以下内容也可以工作(即使已经存在一个或多个external_id值)。
insert into tt_t(external_id)
select *
from (values (1),(2),(3)) x (external_id)
where not exists (select *
from tt_t
where external_id = x.external_id);