1

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

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;

两个触发器都更新bl表的 process_type 列。如果我更新ot表,bl表的触发器最后触发,因此 process_type 的值是 UPDATED 但我希望当ot表被更新或插入时,ot表的触发器最后触发并且 process_type 值将被删除。

我怎样才能做到这一点?

4

2 回答 2

0

您可以执行以下操作:

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;
于 2013-07-22T19:48:22.053 回答
0

我会从@Thomas 的解决方案开始,但根据您随后的评论,很明显,目前您没有可靠的方法让bl表知道是否process_type应该设置为 UPDATED 或保留 DELETED。

因此,您可能需要构建一些方法ot来告知bl该行将保留为 DELETED。

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

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

另一种选择是在触发器中放置一个条件,bl_process_type_updated如果更新来自触发器,则将其关闭bl_process_type_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;

顺便说一句,你必须摆脱这些WHEN OTHERS THEN NULL;位。你永远不应该隐藏所有的例外。

于 2013-07-23T01:09:04.100 回答