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.