上周,我发现我after insert or update trigger
的工作不正常。在我禁用并启用它之后,它又开始工作了。
我还不知道它为什么停止工作。有什么办法可以解决这个问题吗?因为这个触发器是记录日常工作的价值,并用于报告目的。如果这个触发器在没有我通知或错误的情况下在几天内失效,我将陷入困境。
我正在使用 Oracle 10g,使用 sqldeveloper 访问数据库
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,则触发器将无效,但如果执行触发语句,它仍将执行。如果触发器重新编译失败,触发语句会报错
触发器似乎也有可能像声明的那样正常工作,但不像您预期的那样工作。例如,new.sysid 可能不大于 0(请记住 NULL 不大于 0)导致
WHEN
不满足子句。可能是您的SELECT
语句返回的值小于或等于 0,从而导致您INSERT
没有被执行。如果其中一个TEMPLATE.wf_step
或TEMPLATE.step_stage
有一个列STEP_ID
,则该WHERE
子句将解释
STEP_ID
为表中的列,而不是您的局部变量STEP_ID
。PL/SQL 开发人员通常为局部变量添加前缀(即L_STEP_ID
,而不是STEP_ID
)的原因之一是避免无意中使用表中的列也使用的名称,因为众所周知,这类范围解析问题难以调试。这可能取决于触发器“停止工作”的原因。
如果它被触发,但没有运行完成,您可以在
EXCEPTION
块中放置一些东西来触发消息。如果它被完全禁用,你必须找到一些在它运行时是真的特征(例如,我有一些触发器填充了一种难以动态计算的物化视图。我有一个 cron 作业来检查当该表中的最新记录是,如果它太旧,它会报告它)。如果您没有类似的明显内容,则始终可以有一个表仅用于跟踪上次运行触发器的时间,并使用当前时间对其进行更新。
当然,这些都没有真正帮助 Justin Cave 提到的情况,因为变量名称解析,命令被误解了。你可以
else
在if ( stepSysid>0)
分支上放一个,如果这是不应该发生的事情,就放在那里报告。