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

Oracle là Giải pháp thay thế của các bảng thay đổi

Lỗi trình kích hoạt thay đổi Oracle xảy ra khi trình kích hoạt tham chiếu đến bảng sở hữu trình kích hoạt, dẫn đến thông báo “ORA-04091:tên bảng đang thay đổi, trình kích hoạt / hàm có thể không nhìn thấy nó”.

Hãy xem các cách giải quyết hiện có.

Cái đầu tiên, thông qua gói, là cổ và có vẻ hiệu quả, tuy nhiên, cần nhiều thời gian để chuẩn bị và chạy nó. Cách thứ hai đơn giản và được thực hiện bằng cách sử dụng trình kích hoạt phức hợp.

create table turtles 
as
select 'Splinter' name, 'Rat' essence from dual union all
select 'Leonardo', 'Painter' from dual union all
select 'Rafael', 'Painter' from dual union all
select 'Michelangelo', 'Painter'  from dual union all
select 'Donatello', 'Painter'  from dual;

Khi Splinter biến từ một con chuột thành một sensei, các họa sĩ sẽ phải tự động biến thành ninja. Trình kích hoạt này có vẻ phù hợp:

create or replace trigger tr_turtles_bue
before update of essence
on turtles
for each row
when (
  new.name = 'Splinter' and old.essence = 'Rat' and new.essence = 'Sensei'
)
begin
  update turtles
     set essence = 'Ninja'
   where essence = 'Painter';  
end;

Tuy nhiên, khi cập nhật hồ sơ:

update turtles
   set essence = 'Sensei'
 where name = 'Splinter'

Lỗi sau xảy ra:

ORA-04091:bảng SCOTT.TURTLES đang thay đổi, trình kích hoạt / chức năng có thể không nhìn thấy nó

Hãy xóa trình kích hoạt này:

drop trigger tr_turtles_bue;

Phương pháp 1: Sử dụng gói và trình kích hoạt cấp hướng dẫn.

create or replace package pkg_around_mutation 
is
  bUpdPainters boolean;
  procedure update_painters;  
end pkg_around_mutation;
/

create or replace package body pkg_around_mutation
is
  procedure update_painters
  is
  begin   
    if bUpdPainters then
      bUpdPainters := false;
      update turtles
         set essence = 'Ninja'
       where essence = 'Painter';
    end if;
  end;  
end pkg_around_mutation;
/

create or replace trigger tr_turtles_bue
before update of essence
on turtles
for each row
when (
  new.name = 'Splinter' and old.essence = 'Rat' and new.essence = 'Sensei' 
)
begin
  pkg_around_mutation.bUpdPainters := true;  
end tr_turtles_bue; 
/

create or replace trigger tr_turtles_bu
after update
on turtles
begin
  pkg_around_mutation.update_painters;  
end tr_turtles_bu;
/

Phương pháp 2: Sử dụng trình kích hoạt DML phức hợp (khả dụng bắt đầu với Oracle 11g).

create or replace trigger tr_turtles_ue
  for update of essence
  on turtles
  compound trigger
    bUpdPainters  boolean;
 
  before each row is
  begin
    if :new.name = 'Splinter' and :old.essence = 'Rat' and :new.essence = 'Sensei' then
      bUpdPainters := true;
    end if;
  end before each row;
  
  after statement is
  begin
    if bUpdPainters then
      update Turtles
         set essence = 'Ninja'
       where essence = 'Painter';
    end if;
  end after statement;
end tr_turtles_ue;

Hãy thử những cách sau:

update turtles
   set essence = 'Sensei'
 where name = 'Splinter'

Ngay cả khi bạn phải đối mặt với một trường hợp đột biến phức tạp hơn, bạn có thể sử dụng ý tưởng được đề cập ở trên như một cách giải quyết. Trong trình kích hoạt cấp lệnh, không giống như trình kích hoạt cấp hàng, không có đột biến nào xảy ra. Bạn có thể sử dụng các biến (thẻ, chốt, bảng PL SQL) trong một gói bổ sung hoặc các biến là toàn cục cho tất cả các phần của trình kích hoạt phức hợp, tốt hơn là bắt đầu với phiên bản Oracle 11g. Vì vậy, bây giờ bạn cũng biết kung fu.

Bạn có thể tìm thêm thông tin về trình kích hoạt tại:Trình kích hoạt DML kết hợp

Vui lòng thêm bất kỳ nhận xét nào.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 7 điều cần biết về các ngăn trên Cơ sở hạ tầng đám mây Oracle

  2. chọn rownum từ mức lương mà rownum =3;

  3. ORA-00918:cột được xác định không rõ ràng trong SELECT *

  4. Chuyển đổi Dấu thời gian Unix thành Giá trị ngày tháng trong Oracle

  5. Hàm NANVL () trong Oracle