Oracle不同的表';s触发命令

Oracle不同的表';s触发命令,oracle,triggers,Oracle,Triggers,我有两个触发器: 其中一项: create or replace TRIGGER bl_process_type_updated before update ON bl REFERENCING NEW AS NEW OLD AS OLD FOR EACH ROW BEGIN :new.process_type := 'UPDATED'; EXCEPTION WHEN OTHERS THEN NULL; END; 另一个: create or replace TRI

我有两个触发器: 其中一项:

create or replace
TRIGGER bl_process_type_updated
before update
ON bl
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN 
    :new.process_type := 'UPDATED';
EXCEPTION    
 WHEN OTHERS THEN  
 NULL; 
 END;
另一个:

create or replace
TRIGGER bl_process_type_deleted
after insert or update
ON ot
FOR EACH ROW
DECLARE
    building_id bl.bl_id%TYPE;
BEGIN 
   building_id := :new.bl_id ;
   if(:new.status = 'Sold' or :new.status = 'LeaseTerminated') then
      update bl set process_type='DELETED' where bl_id = building_id;
    end if;
 EXCEPTION    
 WHEN OTHERS THEN  
 NULL; 
 END;
这两个触发器都会更新表的进程类型列。如果我更新
ot
表,
bl
表的触发器上次触发,因此进程类型的值会更新,但我希望在更新或插入
ot
表时,
ot
表的触发器上次触发和进程类型值会被删除


我如何才能做到这一点?

您可以执行以下操作:

create or replace TRIGGER bl_process_type_updated
before update
ON bl
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN 
    if :new.process_type <> 'DELETED' then
        :new.process_type := 'UPDATED';
    end if;
EXCEPTION WHEN OTHERS THEN  
    NULL; 
END;
创建或替换触发器bl\u进程\u类型\u更新
更新前
关于bl
引用新旧相同
每行
开始
如果:new.process\u类型为“已删除”,则
:new.process_type:=“已更新”;
如果结束;
当其他人
无效的
结束;

我本来会从@Thomas的解决方案开始,但根据您随后的评论,很明显目前您没有可靠的方法让
bl
表知道
流程类型是否应设置为更新或保留删除

因此,您可能需要构建一些方法,通过这些方法,
ot
可以告诉
bl
行将被保留为已删除

首先,不要试图影响触发火灾的顺序——你只会让自己陷入困境

一种选择是完全放弃使用触发器的想法,即创建一个API(PL/SQL包),对这些表执行插入和更新,并处理您需要的后续逻辑。显然,您需要修改应用程序以使用API。一种简单的方法是将视图放在表的前面,同时使用Instead而非触发器来调用API

另一个选项是在
bl\u process\u type\u updated
触发器中设置一个条件,如果更新来自
bl\u process\u type\u deleted
触发器,则该触发器将关闭该条件。交换机必须位于数据库包中,例如:

CREATE OR REPLACE PACKAGE bl_trigger_pkg AS
  bl_trigger_enabled BOOLEAN := TRUE;
END;
/

create or replace
TRIGGER bl_process_type_updated
  before update
  ON bl
  REFERENCING NEW AS NEW OLD AS OLD
  FOR EACH ROW
BEGIN 
  IF bl_trigger_pkg.bl_trigger_enabled THEN
    :new.process_type := 'UPDATED';
  END IF;
END;

create or replace
TRIGGER bl_process_type_deleted
  after insert or update
  ON ot
  FOR EACH ROW
DECLARE
   building_id bl.bl_id%TYPE;
BEGIN 
   building_id := :new.bl_id ;
   if(:new.status = 'Sold' or :new.status = 'LeaseTerminated') then
      bl_trigger_pkg.bl_trigger_enabled := FALSE;
      update bl set process_type='DELETED' where bl_id = building_id;
      bl_trigger_pkg.bl_trigger_enabled := TRUE;
   end if;
END;

顺便说一句,当别人为空时,你必须去掉
位。决不能只隐藏所有异常。

Oracle 11g触发器语法现在包含以下子句,以保证使用相同计时点定义的触发器的执行顺序。但是我的触发器计时点不同。下面的子句在这里不适用,因为触发器位于不同的表上,并且位于不同的计时点。对不起,我输入了一个错误。现在试试。它可以工作,但是如果记录被标记为已删除,它将永远不会被更新。此状态在“已删除”和“已更新”之间经常更改。这是暂时的解决办法。