在我看来,通常应该在事务结束时检查约束。
所以,在一个简单的示例中,我们有一个表 A
,其中唯一的列 P
是它的主键,还有一个表 B
与主键 P
和外键 F
在 A.P
上,以下应该工作(在空表上):
begin
insert into B (P, F)
values (1, 1);
insert into A (P)
values (1);
commit;
end;
但是,Oracle 给我错误(德语):
[23000][2291] ORA-02291: Integritäts-Constraint (DATABASE.AB_constraint) verletzt - übergeordneter Schlüssel nicht gefunden
ORA-06512: in Zeile 3
Position: 0
转化为违反了完整性约束 - 未找到引用的 key 。如果我颠倒顺序
begin
insert into A (P)
values (1);
insert into B (P, F)
values (1, 1);
commit;
end;
它工作正常。 Oracle 中事务结束时是否未验证约束?如果是这样,是否有任何方法可以强制执行此行为?
在Oracle docs据称(遵循 ACID 属性)
[t]he transaction takes the database from one consistent state to another consistent state.
因此可以预期,两者之间的状态不一定必须一致。这当然适用于 Oracle 提供的示例:资金从一个账户转移到另一个账户,而在两者之间,资金总额不匹配(不一致),因为资金从一个账户中移除,但不是还添加到另一个。那么为什么外键约束似乎不一样呢?
最佳答案
And if so, is there any way of enforcing this behaviour
是的,就是这样。它被称为延迟约束。
如果约束被延迟,则在事务结束时检查它,而不是在执行语句时检查。
alter table some_table
add constraint fk_something
foreign key (some_column) references other_table(pk_column)
deferrable initially deferred;
参见 this answer关于 initially deferred
之间区别的解释和 initially immediate
关于sql - Oracle:什么时候检查约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60008365/