Рассмотрит следующий код:Есть ли способ поймать исключение отложенного ограничения в pgsql?
drop table if exists demo cascade;
drop table if exists child cascade;
create table demo
(
id bigint not null
constraint demo_pk primary key
);
create table child
(
id bigint not null
constraint child_pk primary key,
pid bigint,
constraint child_pid_fk
foreign key (pid)
references demo (id)
deferrable initially deferred -- remove this line and exceptions get caught
);
insert into demo values (1);
insert into child values (11, 1);
do language plpgsql $$
begin
delete from demo where id = 1;
exception
when others then
raise notice 'exception caught';
end;
$$;
Я хотел бы, чтобы поймать любое исключение, брошенное ограничениями, но из соображений производительности я отложить проверку ограничений до принятия (deferrable initially deferred
). Есть ли способ поймать исключения без поворота immediate
режим?
Нет, вы не можете, потому что по определению отложенное ограничение не проверяется до фиксации. Вам нужно будет обработать исключение в коде, запущенном, что SQL –
Вы можете попробовать и запустить 'SET CONSTRAINTS child_pid_fk IMMEDIATE;' после оператора 'DELETE', в контексте SQL, который запускает проверку ограничений; однако я не уверен, что это правда в контексте plpgsql. - Редактирование: просто увидел, что вы написали, что ищете другие варианты, кроме этого. Я не думаю, что есть другие варианты. – pozs
@pozs: Я думаю, что ты был на правильном пути в конце концов. Я думаю, что OP просто не хочет менять определение таблицы, 'SET CONSTRAINTS' - это то, что ему нужно. –