Oracle
 sql >> база данни >  >> RDS >> Oracle

Деактивирайте тригерите и активирайте отново тригерите, но междувременно избягвайте промяна на таблицата

Малко по-различен подход е да запазите тригерите активирани, но да намалите (ако не и напълно да премахнете) тяхното въздействие, като добавите 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. При моето тестване има разлика от порядък на величина.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да настроя времето за изчакване на връзката на oracle db в приложението за стартиране на spring

  2. Oracle Concurrent Manager – CP анализатор за E-Business Suite

  3. Актуализиране на SQL, изтриване и вмъкване едновременно

  4. Как мога да получа броя на дните между 2 дати в Oracle 11g?

  5. SSRS 2016 Източник на данни няма да показва тип връзка на Oracle