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