1

the issue: i need to do something like this

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);

but execution raises an error

SQL Error [55000]: ERROR: currval of sequence "tt_t_id_seq" is not yet defined in this session

solution: there is a way to solve this with anonymous code block

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;
$$
;

but anonymous blocks has some restrictions e.g. Dapper parameters not working with PostgreSQL through npgsql connection, is postgres anonymous function parameterization supported?

how do i fix it without anonymous code block (UPD: and without any DDL changes)?

2 Answers 2

1

probable solution:

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);

shorter code has been proposed to me

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);

but i'm not sure if nextval will be calculated first

Sign up to request clarification or add additional context in comments.

Comments

1

What about using a default value:

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);

In theory it shouldn't be possible that another nextval() is called between the one for the id and the lastval(). However I am not 100% sure if there are some corner cases that I don't know of.

The following works as well (even if one or more of the external_id values already exist).

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);

1 Comment

Unfortunately I can not make any DDL changes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.