由于表变异,以下触发器不起作用,因为我认为触发器中的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_”。
答案 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调用。
分享并享受。