【问题标题】:Why `not deferrable` constraint is deferred when using `with`?为什么在使用`with`时会延迟`not deferable`约束?
【发布时间】:2023-03-27 16:33:01
【问题描述】:
create table T1 (
    id bigint NOT NULL primary key,
    a bigint unique not null
);
create table T2 (
    id int not null primary key,
    b bigint,
    foreign KEY(id) references T1(id) not deferrable
);
alter table T1 add constraint fk_id foreign key (id) references T2(id) not deferrable;    

--Statement 1
with ins as (
        insert into T1(id, a) values(15, 4) returning id
)
insert into T2(id, b) values(15, 3);

--Statement 2
with ins as (
        insert into T2(id, b) values(14, 4) returning id
)
insert into T1(id, a) values(14, 3);

--Statement 3 (gives error)
with upd as (
        update T1 set a = 4 where id = 14 returning id
)
update T1 set a = 3 where id = 15;

当这个脚本在 PostgreSQL 中运行时,为什么语句 1 和 2 有效,而只有语句 3 给出了错误,即使两个外键约束都明确不可延迟?

【问题讨论】:

    标签: sql postgresql


    【解决方案1】:

    根据the docs 对每一行检查不可延迟的唯一约束,这与仅在语句末尾检查它们的标准规范相反。

    当 UNIQUE 或 PRIMARY KEY 约束不可延迟时,PostgreSQL 会在插入或修改行时立即检查唯一性。 SQL 标准规定,唯一性应仅在语句末尾强制执行...

    但是标准规范的这个例外只是为了唯一性,而不是外键。如果外键约束是不可延迟的,或者它们是可延迟的但不是延迟的,则在语句末尾检查外键约束。由于前两个示例中的语句结束时所有问题都已解决,因此没有错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-28
      • 2010-11-03
      • 2020-04-19
      • 2013-05-15
      • 1970-01-01
      • 2013-12-24
      • 1970-01-01
      • 2015-06-28
      相关资源
      最近更新 更多