sql - Oracle:什么时候检查约束?

标签 sql oracle transactions constraints

在我看来,通常应该在事务结束时检查约束。

所以,在一个简单的示例中,我们有一个表 A,其中唯一的列 P 是它的主键,还有一个表 B 与主键 P 和外键 FA.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/

相关文章:

php - 使用 SUM() 问题选择付款的简单单选按钮

mysql - 获取组内最新记录

hibernate - 回滚是否终止 session ?

MYSQL 选择重复的行,其中重复 2 或 3 列值

mysql - SQL:查找 A 列中的记录与 B 列中的重复记录

database - (oracle) 与手动运行插入相比,在存储过程中插入非常慢

java - 内部错误 : Unknown or unimplemented accessor type: 9

Oracle 模式设计 : Seperate Schema with I/O Overhead?

java - AOP、Spring 和事务范围界定

ruby-on-rails - Grape API + Active Record 包装事务