SQL块中的语句引发完整性约束,但不作为单个语句

时间:2019-01-11 18:20:19

标签: oracle plsql

我正在运行遵循父/子依赖项的delete语句块。执行该块时,一条语句引发完整性约束。但是,当单独执行该语句时,不会产生任何错误。

我已经逐步解决了依赖关系,并正确地将delete语句排序为从子级到父级。当一个或另一个不满足指示要删除记录的基本要求时,我添加了逻辑以包括父母或子女。

begin 
...
delete from rma_receipts where rma_detail_id in (select id from rma_detail where rma_id in (select id from rma where nvl(eplant_id, 1) in (1, 3)));
commit;
--constraint being triggered
delete from rma_detail where rma_id in (select id from rma where eplant_id in (1, 3));
... 
end;

不应清除任何约束,因为RMA_RECEIPTS中的所有子级都已清除。如果我分别运行两个语句,则不会产生任何约束。执行该块时,将产生此错误,表明无法删除rma_detail,因为rma_receipts记录引用了它。 (但没有。)

    Error report -
    ORA-02292: integrity constraint (FK_RMA_RECE_REF_23860_RMA_DETA)         violated - child record found
ORA-06512: at line 60
02292. 00000 - "integrity constraint (%s.%s) violated - child record found" *Cause:    attempted to delete a parent key value that had a foreign
           dependency.
*Action:   delete dependencies first then parent or disable constraint.

为什么这会在一个区块中发生?而不是个别陈述?

1 个答案:

答案 0 :(得分:0)

一般方法:

delete from child_table where parent_key = ...
delete from parent_table where parent_key = ... 
如果在两个步骤之间包含提交,则

容易出错。由于明智的时机,您可能会遇到以下问题:

会议1:

delete from child_table where parent_key = ...
commit

会议2:

insert a new row into child table for the same parent key

会议1:

delete from parent_table where parent_key = ... 

您会收到一条错误消息,因为存在(新的)子记录。

解决方案很简单-删除提交。然后,取决于谁先进入,可能会发生两种情况。

会议1:

delete from child_table where parent_key = ...
delete from parent_table where parent_key = ... 

会议2

tries to insert a new row - and will be blocked waiting for session 1 to either rollback or commit

OR

会议1

delete from parent_table where parent_key = ... 

会议2:

insert a new row into child table for the same parent key

会议1:

delete from parent_table where parent_key = ... 

,在会话2回滚或提交之前,会话1将被禁止删除父对象。无论哪种情况,最终都将删除所有父/子记录或保留所有记录,而不是损坏的混合物。