Oracle Trigger创建 - 表正在变异;触发器可能无法读取或修改它

时间:2013-07-24 10:47:46

标签: oracle plsql triggers mutating-table

由于表变异,以下触发器不起作用,因为我认为触发器中的SQL语句不能对变异表执行,但是因为我不在11g上,所以无法创建复合触发器。我已尝试在声明部分中包含PRAGMA AUTONOMOUS TRANSACTION;,但这不会编译。有人能为我提供最好的解决方案吗?

create or replace 
trigger fb_pers_id_check2_tr
  --after insert on ifsapp.person_info_tab
  before insert on ifsapp.person_info_tab      
for each row
begin
  declare
--  pragma autonomous_transaction;
    v_pid_ person_info_tab.person_id%type;
    format_name_ person_info_tab.name%type;
  begin

  v_pid_ := :new.person_id;

  select regexp_replace(upper(:new.name), '\W')
    into format_name_
  from ifsapp.person_info_tab
  where person_id = v_pid_;

  if length(v_pid_) < 3 and (length(format_name_) < 21 and v_pid_ <> format_name_) then
    raise_application_error(-20001, 'Person ID: ' || v_pid_ || 'is not valid, please enter a valid     Person ID, e.g. "' || format_name_ || '".');
  end if;
end;
end fb_pers_id_check2_tr;

N.B。在简单的英语中,此触发器旨在阻止用户设置长度小于3个字符的人员ID,如果长度少于21个字符,则不等于变量“format_name_”。

1 个答案:

答案 0 :(得分:2)

Oracle不允许行触发器读取或修改定义触发器的表。但是,如果PERSON_ID是PERSON_INFO_TAB上的PRIMARY或UNIQUE键(看起来它是在单例SELECT中使用的情况),您实际上不需要读取表 - 只需在适当的地方使用OLD或NEW值: / p>

create or replace trigger fb_pers_id_check2_tr
  before insert on ifsapp.person_info_tab
  for each row
declare
  v_pid_ person_info_tab.person_id%type;
  format_name_ person_info_tab.name%type;
begin
  v_pid_ := :new.person_id;

  format_name_ := REGEXP_REPLACE(UPPER(:new.name), '\W');    

  if length(v_pid_) < 3 and
     length(format_name_) < 21 and
     v_pid_ <> format_name_
  then
    raise_application_error(-20001, 'Person ID: ' || v_pid_ ||
                            ' is not valid, please enter a valid' ||
                            ' Person ID, e.g. "' || format_name_ || '".');
  end if;
end fb_pers_id_check2_tr;

这里的代码正在检查NAME的NEW值(我认为这是正确的,因为它似乎是验证输入),但如果意图是检查OLD值,则更改很简单:NEW to:OLD in REGEXP_REPLACE调用。

分享并享受。