Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Tắt trình kích hoạt và bật lại trình kích hoạt nhưng tránh thay đổi bảng trong thời gian chờ đợi

Một cách tiếp cận hơi khác là giữ cho các trình kích hoạt được bật nhưng giảm (nếu không phải là loại bỏ hoàn toàn) tác động của chúng, bằng cách thêm when mệnh đề như:

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;
/

Sau đó, trong quy trình của bạn, hãy thêm cuộc gọi tại bắt đầu như bước 'vô hiệu hóa trình kích hoạt' của bạn:

dbms_application_info.set_client_info('BATCH');

và xóa nó một lần nữa vào cuối, đề phòng trường hợp phiên vẫn còn hoạt động và được sử dụng lại (vì vậy bạn cũng có thể muốn thực hiện việc này trong một trình xử lý ngoại lệ):

dbms_application_info.set_client_info(null);

Bạn cũng có thể sử dụng mô-đun hoặc hành động hoặc kết hợp. Mặc dù cài đặt đó được áp dụng, trình kích hoạt sẽ vẫn được đánh giá nhưng sẽ không kích hoạt, vì vậy bất kỳ điều gì xảy ra bên trong sẽ bị bỏ qua - nội dung trình kích hoạt không chạy, vì tài liệu đặt nó.

Đây không phải là điều dễ hiểu vì không có gì thực sự ngăn cản những người dùng / ứng dụng khác thực hiện các cuộc gọi giống nhau, nhưng nếu bạn chọn một chuỗi mô tả hơn và / hoặc kết hợp các cài đặt, điều đó sẽ phải có chủ ý - và tôi nghĩ bạn chủ yếu lo lắng về tai nạn không phải là tác nhân xấu.

Kiểm tra tốc độ nhanh với một bộ kích hoạt vô nghĩa chỉ làm chậm mọi thứ một chút.

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);

Có một chút thay đổi so với việc thực hiện cuộc gọi từ xa, nhưng tôi đã chạy một vài lần và rõ ràng là chạy với trình kích hoạt đơn giản rất giống với chạy với trình kích hoạt bị ràng buộc mà không có bộ BATCH và cả hai đều chậm hơn nhiều so với chạy không có trình kích hoạt hoặc với trình kích hoạt bị ràng buộc với bộ BATCH. Trong thử nghiệm của tôi, có một thứ tự khác biệt về cường độ.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để thêm các số 0 ở đầu vào ngày tháng trong Oracle?

  2. Tạo chế độ xem Oracle với ID được tạo cơ sở dữ liệu từ Đối tượng trình tự

  3. Làm cách nào để sử dụng TẠO HOẶC THAY THẾ?

  4. Xóa số giờ trùng lặp khỏi số ngày không làm việc

  5. Sắp xếp các hàng bằng cách sử dụng các cột từ số lượng ít hơn giá trị null đến không có giá trị nào