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.