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

Oracle 是否可以比较触发器中的其他表?,oracle,Oracle,我有一个数据库,其中的表用外键链接在一起,而链中的最后一个表本身也有一个外键。我想在级联打开的情况下删除它们,例如链中的最后一个。除非它的父记录有某个值,否则应该将其设置为null。我想我应该用一个触发器来实现这一点:每当最后一个表更新时,如果它自身的外键被设置为null,则检查父记录中的字段,如果它是值“default”,则删除最后一个表中的记录 然而,我在网上并没有找到任何关于比较另一个表中的父记录的帮助 这可能吗?如果您不能真正删除上一个表中的记录(表的变化问题),但您可以更新一个状态字段

我有一个数据库,其中的表用外键链接在一起,而链中的最后一个表本身也有一个外键。我想在级联打开的情况下删除它们,例如链中的最后一个。除非它的父记录有某个值,否则应该将其设置为null。我想我应该用一个触发器来实现这一点:每当最后一个表更新时,如果它自身的外键被设置为null,则检查父记录中的字段,如果它是值“default”,则删除最后一个表中的记录

然而,我在网上并没有找到任何关于比较另一个表中的父记录的帮助


这可能吗?

如果您不能真正删除上一个表中的记录(表的变化问题),但您可以更新一个状态字段,指示该记录已被逻辑删除(未测试):


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


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

您可能有某种API(即存储过程)来从父表中删除记录。该API应该在对父表发出
DELETE
之前查询最后一个表。它应该负责更新链中的最后一个表以及从父表中删除数据

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

  • 使用父表中的主键集合创建包
  • 创建用于初始化此集合的before语句触发器
  • 创建一个行级触发器,用SQL语句修改的主键填充集合
  • 创建一个after语句触发器,该触发器在集合上进行迭代并发出所需的任何DML(与行级触发器不同,表A上的语句级触发器可以查询或修改表A)

如果您使用的是11g,那么可以使用带有before语句、after row语句和after语句节的复合触发器来简化这一过程。但是您仍然需要尝试协调许多移动的部分。

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

您可能有某种API(即存储过程)来从父表中删除记录。该API应该在对父表发出
DELETE
之前查询最后一个表。它应该负责更新链中的最后一个表以及从父表中删除数据

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

  • 使用父表中的主键集合创建包
  • 创建用于初始化此集合的before语句触发器
  • 创建一个行级触发器,用SQL语句修改的主键填充集合
  • 创建一个after语句触发器,该触发器在集合上进行迭代并发出所需的任何DML(与行级触发器不同,表A上的语句级触发器可以查询或修改表A)

如果您使用的是11g,那么可以使用带有before语句、after row语句和after语句节的复合触发器来简化这一过程。但仍有许多移动的片段需要协调。

父表中的记录要么直接被删除,要么是因为父表的父表上存在级联约束。我所有的数据库交互都是通过php和OCI8进行的module@AsherMaximum-但您可能仍然有一个用于在PHP代码中从父表中删除行的API,对吗?如果您有一层存储过程来处理这种数据逻辑,那就更好了。但是没有什么可以阻止PHP过程发出多个DML语句来删除父行(显然,由于您的体系结构,您将导致更多的网络等待)。是的,这是我的下一个选择,从PHP中手动执行级联删除。这是一个很好的选择,我只是希望避免它,因为我的表结构有许多链接在一起的表,比如:(>表示子记录)
位置->建筑->地板->房间->机架->设备->端口
我希望能够删除
建筑
位置
,并将其级联到端口。由于端口本身也有fk,所以将其设置为null,除非device.name==default,在这种情况下,delete-portI猜测更好的问题可能是“您能创建一个对其有条件语句的on-delete约束吗?”父表中的记录要么直接被删除,要么是因为父表的父表上存在级联约束。我所有的数据库交互都是通过php和OCI8进行的module@AsherMaximum-但您可能仍然有一个用于在PHP代码中从父表中删除行的API,对吗?如果您有一层存储过程来处理这种数据逻辑,那就更好了。但是没有什么可以阻止PHP过程发出多个DML语句来删除父行(显然,由于您的体系结构,您将导致更多的网络等待)。是的,这是我的下一个选择,从PHP中手动执行级联删除。这是一个很好的选择,我只是希望避免它,因为我的表结构有很多链
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;