首先,我要感谢psaraj12的努力。
我找到了解决方案。 Oracle强迫我们不要在每一行之前使用选择查询。Oracle trigger error ORA-04091
我正在尝试检查是否存在彼此交叉的价值差距。让我快速解释一下。
记录1:公司AA:距离差距-> 100-200建议2:公司AA:距离差距-> 200-300有效Rec 3:公司AA:间距-> 250-450无效Rec 4:公司JL:间距-> 250-450有效
记录3无效,因为它在记录2的距离值之间。Rec 4有效,因为公司与众不同
因此我写了一个触发器来防止它。
create or replace trigger ab_redemption_billing_mpr
after insert or update on redemption_billing_mpr
for each row
declare
v_is_distance_range_valid boolean;
begin
v_is_distance_range_valid := p_redemption_billing.is_distance_range_valid(:new.id,
:new.redemption_billing_company,
:new.distance_min,
:new.distance_max,
'redemption_billing_mpr');
if not v_is_distance_range_valid then
raise_application_error(-20001, 'This is a custom error');
end if;
end ab_redemption_billing_mpr;
功能:
function is_distance_range_valid(p_id in number,
p_company in varchar2,
p_distance_min in number,
p_distance_max in number,
p_table_name in varchar2) return boolean is
d_record_number number;
begin
execute immediate 'select count(*) from ' || p_table_name || ' r
where r.redemption_billing_company = :1
and (:2 between r.distance_min and r.distance_max or :3 between r.distance_min and r.distance_max)
and r.id = nvl(:4, id)'
into d_record_number
using p_company, p_distance_min, p_distance_max, p_id;
if (d_record_number > 0) then
return false;
else
return true;
end if;
end;
is_distance_range_valid()
可以正常工作。如果返回false,则表示范围检查无效,并且请勿插入或更新。
[当我创建场景以捕获此异常时,oracle提供
ORA-04091:表名正在更改,触发器/函数可能看不到它
并且当我单击调试按钮时,它指向选择count(*)行。
我不知道为什么会收到此错误。预先感谢。
只需检查以下方法是否可以解决您的问题
[创建具有查找is_distance_range_valid验证所需的列的日志表,并在触发器中插入此日志选项卡。主表上的触发器必须为插入或更新触发器之前] >>
在此日志表上创建触发器,并在日志表触发器中进行验证并引发错误。日志表上的触发器必须为在插入或更新触发器之后>]。
此外,仅当主表中已存在该行且该行不属于当前插入或更新的一部分时,此方法才起作用。如果需要验证当前插入或更新,那么我们需要使用:new.column_name进行验证
测试:-
create table t_trg( n number); create table t_trg_log( n number); create or replace trigger trg_t before insert or update on t_trg for each row declare l_cnt number; begin insert into t_trg_log values(:new.n); end trg_t; create or replace trigger trg_t_log after insert or update on t_trg_log for each row declare l_cnt number; begin select count(1) into l_cnt from t_trg where n=:new.n; if l_cnt > 0 then raise_application_error(-20001, 'This is a custom error'); end if; end trg_t_log;
我第一次插入它不会引发错误
insert into t_trg values(7); 1 row inserted.
第二次执行时,出现自定义错误
insert into t_trg values(7); Error report - ORA-20001: This is a custom error ORA-06512: at "TRG_T_LOG", line 7 ORA-04088: error during execution of trigger 'TRG_T_LOG' ORA-06512: at "TRG_T", line 4 ORA-04088: error during execution of trigger 'TRG_T'
Update
:-使用复合触发器会在第一次完成插入时引发错误,因为它还会考虑在执行SELECT时我们正在更新或插入的当前行。
首先,我要感谢psaraj12的努力。
我找到了解决方案。 Oracle强迫我们不要在每一行之前使用选择查询。Oracle trigger error ORA-04091
所以我写了这个,它起作用了。
create or replace trigger ab_redemption_billing_mpr for insert or update on redemption_billing_mpr compound trigger v_is_distance_range_valid boolean; id redemption_billing_mpr.id%type; redemption_billing_company redemption_billing_mpr.redemption_billing_company%type; distance_min redemption_billing_mpr.distance_min%type; distance_max redemption_billing_mpr.distance_max%type; after each row is begin id := :new.id; redemption_billing_company := :new.redemption_billing_company; distance_min := :new.distance_min; distance_max := :new.distance_max; end after each row; after statement is begin v_is_distance_range_valid := p_redemption_billing.is_distance_range_valid(id, redemption_billing_company, distance_min, distance_max, 'redemption_billing_mpr'); if not v_is_distance_range_valid then raise_application_error(-20001, 'This is a custom error'); end if; end after statement; end ab_redemption_billing_mpr;
我们必须使用复合触发器来处理它。
首先,我要感谢psaraj12的努力。
我找到了解决方案。 Oracle强迫我们不要在每一行之前使用选择查询。Oracle trigger error ORA-04091