PostgreSQL使用条件将当前序列值插入另一个字段

PostgreSQL使用条件将当前序列值插入另一个字段,postgresql,Postgresql,问题是: 我需要这样做 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 whe

问题是: 我需要这样做

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”的currval

解决方案: 有一种方法可以通过匿名代码块来解决这个问题

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更改)的情况下修复它?

可能的解决方案:

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

使用默认值怎么样:

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);
理论上,在
id
lastval()之间不可能调用另一个
nextval()
。然而,我不能100%确定是否有一些我不知道的角落案例

以下方法也可以工作(即使已经存在一个或多个外部_id值)


不幸的是,我无法进行任何DDL更改。
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);