是否可以比较触发器中的其他表?

时间:2011-06-08 13:38:03

标签: oracle

我有一个数据库,其中包含与外键链接在一起的表,链中的最后一个表也有自己的外键。我想用cascade删除它们,为链中的最后一个删除它们。除非父记录具有特定值,否则应将其设置为null。我想我会用触发器执行此操作:每当更新最后一个表时,如果自身的外键已设置为null,请检查父记录中的字段,如果它是值“default”,则删除该记录最后一张桌子。

但是,我没有在网上找到任何帮助,指出比较另一个表中的父记录。

这可能吗?

2 个答案:

答案 0 :(得分:3)

通常,表A上的行级触发器无法查询表A.这样做通常会引发变异表异常(ORA-04091)。因此,触发器通常不是正确的解决方案。

据推测,您可以使用某种API(即存储过程)从父表中删除记录。该API应在针对父表发出DELETE之前查询此最后一个表。它应该注意更新链中的最后一个表以及从父表中删除数据。

如果你真的想要一个基于触发器的解决方案,生活会变得更加复杂。您可以通过

解决变异表异常
  • 使用父表中的主键集合创建包
  • 创建初始化此集合的before语句触发器
  • 创建一个行级触发器,使用由SQL语句修改的主键填充集合
  • 创建一个迭代集合的after语句触发器,并发出任何必要的DML(与行级触发器不同,表A上的语句级触发器可以查询或修改表A)。

如果你正在使用11g,你可以使用带有before语句,after after和after语句部分的复合触发器来简化这一点。但是你仍然有许多动作来试图协调。

答案 1 :(得分:1)

AFAIK您将无法真正删除最后一个表中的记录(变异表问题),但您可以更新状态字段,指示记录已被逻辑删除(未经测试):

create or replace trigger last_table_trig
before update on last_table
for each row
declare
  l_parentField varchar2(100);
begin
  if :new.self_ref_fk is null then
     select p.parent_field into l_parentField from parent_table p
     where p.pk = :new.parent_fk;
     if l_parentField = 'default' then
       :new.status := 'DELETED';
     end if;
  end if;
end;