上周,我找到了我的 after insert or update trigger 不起作用。禁用并启用它后,它再次开始工作。

我还不知道为什么它停止工作。有什么方法可以解决吗?因为此触发器正在记录日常工作的价值,并用于报告目的。如果这个触发器在几天内死亡而没有通知或错误,我将在热水中。

我正在使用Oracle 10G,请使用SQLDEVEVER访问DB

My Trigger

create or replace
TRIGGER MASTER.INSTANCE_STEP_TRG 
AFTER INSERT OR UPDATE OF SYSID,STEP_ID,INSTANCE_ID,PARENT_STEP_ID ON MASTER.WF_INSTANCE_STEP 
REFERENCING OLD AS old NEW AS new 
FOR EACH ROW 
WHEN (new.sysid > 0) 
declare 
stepSysid number;
crCode varchar(50);
crDate date;
step_id number;
BEGIN
  step_id := :new.step_id;

  select ss.sysid into stepSysid from TEMPLATE.wf_step ws 
  inner join TEMPLATE.step_stage ss on ss.sysid=ws.stage_id
  where ws.sysid= step_id;


  if ( stepSysid>0) then
    insert into MASTER.fact_cr_progress values(0,:new.instance_id,stepSysid,:new.create_dt);
  end if;

  dbms_output.enable(10000);
  dbms_output.put_line('start print');

END;
有帮助吗?

解决方案

触发器不能简单地停止工作。

可以禁用触发器。扳机可以丢弃。如果DDL已对其引用的一个对象之一完成,则触发器将无效,但是如果执行触发语句,它仍将执行。如果触发器未能成功重新编译,则触发语句将获得错误

ORA-04098: trigger ' MASTER.INSTANCE_STEP_TRG' is invalid and failed re-validation

扳机似乎也可能按照您的预期正确地工作,但触发器正常正常工作。例如,新的。sysid可能不大于0(请记住,零不大于0) WHEN 条款不被满足。可能是你的 SELECT 陈述返回一个小于或等于0的值,从而导致您的 INSERT 不被执行。如果是 TEMPLATE.wf_step 或者 TEMPLATE.step_stage 有一个列 STEP_ID, , 这 WHERE 条款

where ws.sysid= step_id;

会解释 STEP_ID 作为表中的列,而不是您的本地变量 STEP_ID. 。 PL/SQL开发人员通常将前缀添加到本地变量的原因之一(即 L_STEP_ID 而不是 STEP_ID)是为了避免使用表格中的列也使用的名称,因为众所周知,这些范围分辨率问题很难进行调试。

其他提示

这可能取决于触发“停止工作”的原因。

如果它是触发的,但没有完成,您可以在 EXCEPTION 堵塞。

如果它完全被禁用,您必须找到运行时确实如此的特征(例如,我有一些触发器,这些触发器填充了某种物质的视图,这些视图很难即时计算。当该表中的最新记录是,如果它太旧了,它就会报告)。如果您没有这样的明显的东西,那么您总是有一张桌子,该表仅在上次运行时跟踪,并在当前时间进行更新。

当然,这两个都没有真正帮助贾斯汀·凯夫(Justin Cave)提到的情况,由于名称分辨率可变,命令被误解了。你可以放一个 elseif ( stepSysid>0) 分支,并将报告放在那里,如果这是不应该真正发生的事情。

许可以下: CC-BY-SA归因
不隶属于 dba.stackexchange
scroll top