工作遇到的问题 Oracle外键延迟约束

发布 : 2019-07-11 分类 : 数据库 浏览 :

在工作中遇到了一个外键延迟约束的问题

问题:

主子表插入数据时出现 ORA-02291: 违反完整约束条件 (NHMS.SYS_C0014639) - 未找到父项关键字

原因:

检查发现时因为主子表数据一起插入 单主表的数据还没插入完成,子表就开始插入数据,最后就报错了
之前创建表时并没有留意到外键的约束验证类型,使用的是默认 非延迟约束 not deferrable

1
2
--查看表的约束情况
select table_name, constraint_name, status, deferrable, deferred, validated from user_constraints where table_name = 'WM_PURCHASE_DETAIL';

解决方法:

需要将外键约束改成 可延迟默认延迟 deferrable initially deferred
这样当主子表的数据插入后提交事务时进行验证就不会出现违法约束条件的问题了

1
2
3
4
--删除某个表的约束
alter table WM_PURCHASE_DETAIL drop constraint SYS_C0030739;
--重新创建 可延迟默认延迟 的约束
alter table WM_PURCHASE_DETAIL add foreign key (PURCHASE_ID) references WM_PURCHASE on delete cascade deferrable initially deferred;

资料

Oracle中的约束有两种方式,一种是延迟约束,一种是非延迟约束。
非延迟约束就是删除或新增记录时会立刻进行约束条件验证,违法约束就回滚报错。
延迟约束则表示新增删除时不进行约束验证,只有提交时才进行验证,违反就回滚报错。

外键可以设置约束选项有3种

约束选项 解释
not deferrable 不可延迟
deferrable initially immediate 可延迟 未延迟
deferrable initially deferred 可延迟 已延迟

主表删除时子表的删除规则

删除规则 解释
no action 不做任何操作
on delete set null 将外键设置为null
on delete cascade 级联删除
本文作者 : zhouinfo
原文链接 : http://blog.zhouinfo.site/2019/07/11/%E5%B7%A5%E4%BD%9C%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98-Oracle%E5%A4%96%E9%94%AE%E5%BB%B6%E8%BF%9F%E7%BA%A6%E6%9D%9F/
版权声明 : 本博客所有文章除特别声明外,均采用 CC Apache License 2.0 许可协议。转载请注明出处!
留下足迹