Малко по-различен подход е да запазите тригерите активирани, но да намалите (ако не и напълно да премахнете) тяхното въздействие, като добавите when
клауза нещо като:
create or replace trigger ...
...
for each row
when (sys_context('userenv', 'client_info') is null
or sys_context('userenv', 'client_info') != 'BATCH')
declare
...
begin
...
end;
/
След това във вашата процедура добавете извикване в стартиране като вашата стъпка за „деактивиране на задействания“:
dbms_application_info.set_client_info('BATCH');
и го изчистете отново в края, само в случай че сесията остане жива и се използва повторно (така че може да искате да направите това и в манипулатор на изключения):
dbms_application_info.set_client_info(null);
Можете също да използвате модул, или действие, или комбинация. Докато тази настройка е в сила, тригерът все още ще бъде оценен, но няма да се задейства, така че всичко, което се случва вътре, ще бъде пропуснато - тялото на тригера не се изпълнява, тъй като документите сложи го.
Това не е безупречно, тъй като нищо не спира други потребители/приложения да извършват същите повиквания, но ако изберете по-описателен низ и/или комбинация от настройки, това трябва да е умишлено - и мисля, че най-вече тревожат се за злополуки, а не са лоши актьори.
Бърз тест за скорост с безсмислен тригер, който просто забавя нещата малко.
create table t42 (id number);
-- no trigger
insert into t42 (id) select level from dual connect by level <= 10000;
10,000 rows inserted.
Elapsed: 00:00:00.050
create or replace trigger tr42 before insert on t42 for each row
declare
dt date;
begin
select sysdate into dt from dual;
end;
/
-- plain trigger
insert into t42 (id) select level from dual connect by level <= 10000;
10,000 rows inserted.
Elapsed: 00:00:00.466
create or replace trigger tr42 before insert on t42 for each row
when (sys_context('userenv', 'client_info') is null
or sys_context('userenv', 'client_info') != 'BATCH')
declare
dt date;
begin
select sysdate into dt from dual;
end;
/
-- userenv trigger, not set
insert into t42 (id) select level from dual connect by level <= 10000;
10,000 rows inserted.
Elapsed: 00:00:00.460
- userenv trigger, set to BATCH
exec dbms_application_info.set_client_info('BATCH');
insert into t42 (id) select level from dual connect by level <= 10000;
10,000 rows inserted.
Elapsed: 00:00:00.040
exec dbms_application_info.set_client_info(null);
Има малко вариации от извършването на отдалечени повиквания, но стартирах няколко пъти и е ясно, че работата с обикновен тригер е много подобна на работата с ограничен тригер без настройка BATCH, и двете са много по-бавни от работата без тригер или с ограниченият тригер с набор BATCH. При моето тестване има разлика от порядък на величина.