暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 从相互依赖的表中删除。

ASKTOM 2020-05-01
297

问题描述

我正在使用一个系统,以我能想到的最慷慨的术语,它有一个horrendous数据模型。有一组表是 “对等体”,因为它们具有1-1关系,并且表a的PK是表X1到Xn中的PK。表A是 “主”,表X... 是 “辅助” (ORM继承)。所有这些表可能都有相关的子表。表A必须在辅助表中只有1个和1个相关行,当从辅助表中删除一行时,必须从表a中删除相应的行,反之亦然。我不能强制删除总是以表A开头; 它可以在任何对等表启动。我已经尝试了级联删除和最初延迟外键的组合,当只有一个辅助表时,它们可以工作,但是你不能把多个fk放在一个列上,所以它不适用于1 .. n表。我尝试在辅助表上放置一个触发器,该触发器删除父表,而父表又与具有级联删除的其他表相关,但由于数据变异错误而失败。

可悲的是,由于重塑表 (例如组合而不是继承) 是在表外,因此 “最佳” 剩余替代方案似乎是所有删除均由存储过程完成。这就有了Xn的 "n" 部分不是随时间静态的问题。当添加新的对等表时,必须记住更新存储过程,而我的组织已证明该领域存在缺陷。

liveSql脚本的语句3和5对突变数据注释有错误陷阱。在没有错误捕获的情况下,进程在错误上失败。错误捕获后,主行不会被删除。

有什么想法吗?

专家解答

嗯,听起来你有点混乱!

我可以想出几种方法:

-创建一个视图外部连接所有表。在其上放置一个相反的DML触发器,并针对视图运行所有删除
-移除所有的fk...

第一种是我的首选方法;)

create or replace view my_central_view as 
  select m.*, description_1, description_2
  from   my_central_table m
  left join my_auxiliary_table_1 t1
  on     pk = t1.auxiliary_key 
  left join my_auxiliary_table_2 t2
  on     pk = t2.auxiliary_key ;
  
create or replace trigger view_iiud 
instead of insert or update or delete on my_central_view
begin
  if deleting then
    delete my_central_table
    where  pk = :old.pk;
    
    delete my_auxiliary_table_1
    where  auxiliary_key = :old.pk;
    
    delete my_auxiliary_table_2
    where  auxiliary_key = :old.pk;
  end if;
end;
/

delete my_central_view;


尽管这与存储过程存在相同的问题: 人们必须记住更新它!我更喜欢使用存储过程而不是带有intead触发器的视图。但是您的开发团队可能更容易接受这种观点。

删除FKs显然可以完全避免问题。但是带来了自己的数据质量问题!

鉴于:

As new peer tables are added someone has to remember to update the stored procedure, and my organization has demonstrated a deficiency in that area.

我会非常犹豫是否删除FKs。

最终你需要得到存储过程/视图/等的维护。草率的过程最终会咬你的!

但这通常需要组织变革,这很难。祝你好运!
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论