有没有办法在pgsql中捕获延迟约束的异常?

时间:2017-02-10 11:46:07

标签: postgresql exception constraints plpgsql

请考虑以下代码:

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

我想捕获约束引发的任何异常,但出于性能原因,我推迟检查约束直到commit(deferrable initially deferred)。有没有办法在不启用immediate模式的情况下捕获异常?

1 个答案:

答案 0 :(得分:4)

可以为您的交易设置IMMEDIATE的可延迟约束,而无需“立即开启模式”(不更改约束定义)。

这正是这个单独的命令SET CONSTRAINTS的用途:

SET CONSTRAINTS child_pid_fk IMMEDIATE;

或者如果您不知道约束名称:

SET CONSTRAINTS ALL IMMEDIATE;

The manual:

  

SET CONSTRAINTS设置当前交易中约束检查的行为

大胆强调我的。

  

SET CONSTRAINTS更改约束的模式时   DEFERREDIMMEDIATE,新模式会追溯生效:   任何未经检查的未完成的数据修改   在执行期间检查事务的结尾   SET CONSTRAINTS命令。如果违反任何此类约束,则   SET CONSTRAINTS失败(并且不会更改约束模式)。   因此,SET CONSTRAINTS可用于强制检查约束   发生在交易中的特定点。

正是你需要的。