Oracle ORA-04091:表xx_xx正在变异,触发器/函数可能看不到它
因此,我必须创建一个触发器,它将对名为“passengerlist1”的表所做的更改记录到名为“logs”的额外表中 日志表:Oracle ORA-04091:表xx_xx正在变异,触发器/函数可能看不到它,oracle,plsql,triggers,Oracle,Plsql,Triggers,因此,我必须创建一个触发器,它将对名为“passengerlist1”的表所做的更改记录到名为“logs”的额外表中 日志表: create table logs ( p_name varchar(255), p_surname varchar(255), f_id number, time_stamp timestamp ); Passengerlist1表具有以下属性:FLIGHTID、PERSONID、SEATNUMBER。 还有另一个名为PERSON1的表,其属性为:P
create table logs (
p_name varchar(255),
p_surname varchar(255),
f_id number,
time_stamp timestamp
);
Passengerlist1表具有以下属性:FLIGHTID、PERSONID、SEATNUMBER。
还有另一个名为PERSON1的表,其属性为:PERSONID、GIVENNAME、FAMILYNAME、DATEOFBIRTH。这是一个表,我需要从中选择一个人的GIVENNAME和FAMILYNAME,并将其存储到“logs”表中,以防对“PassengerList 1”表进行更改。从“passengerlist1”表中,我只需要选择FLIGHTID并将其存储到“logs”表中
这是我的扳机:
CREATE OR REPLACE TRIGGER log_changes
AFTER INSERT OR UPDATE OR DELETE
ON passengerlist1
FOR EACH ROW
DECLARE
t_name varchar2(255);
t_surname varchar2(255);
BEGIN
BEGIN
IF DELETING THEN
SELECT PERSON1.GIVENNAME INTO T_NAME FROM
PERSON1 JOIN PASSENGERLIST1
ON PERSON1.PERSONID = PASSENGERLIST1.PERSONID
WHERE PASSENGERLIST1.FLIGHTID = :OLD.FLIGHTID;
SELECT PERSON1.FAMILYNAME INTO T_SURNAME FROM
PERSON1 JOIN PASSENGERLIST1
ON PERSON1.PERSONID = PASSENGERLIST1.PERSONID
WHERE PASSENGERLIST1.FLIGHTID = :OLD.FLIGHTID;
INSERT INTO LOGS VALUES (T_NAME, T_SURNAME, :OLD.FLIGHTID, SYSDATE);
END IF;
IF UPDATING THEN
SELECT PERSON1.GIVENNAME INTO T_NAME FROM
PERSON1 JOIN PASSENGERLIST1
ON PERSON1.PERSONID = PASSENGERLIST1.PERSONID
WHERE PASSENGERLIST1.FLIGHTID = :NEW.FLIGHTID;
SELECT PERSON1.FAMILYNAME INTO T_SURNAME FROM
PERSON1 JOIN PASSENGERLIST1
ON PERSON1.PERSONID = PASSENGERLIST1.PERSONID
WHERE PASSENGERLIST1.FLIGHTID = :NEW.FLIGHTID;
INSERT INTO LOGS VALUES (T_NAME, T_SURNAME, :NEW.FLIGHTID, SYSDATE);
END IF;
IF INSERTING THEN
SELECT PERSON1.GIVENNAME INTO T_NAME FROM
PERSON1 JOIN PASSENGERLIST1
ON PERSON1.PERSONID = PASSENGERLIST1.PERSONID
WHERE PASSENGERLIST1.FLIGHTID = :NEW.FLIGHTID;
SELECT PERSON1.FAMILYNAME INTO T_SURNAME FROM
PERSON1 JOIN PASSENGERLIST1
ON PERSON1.PERSONID = PASSENGERLIST1.PERSONID
WHERE PASSENGERLIST1.FLIGHTID = :NEW.FLIGHTID;
INSERT INTO LOGS VALUES (T_NAME, T_SURNAME, :NEW.FLIGHTID, SYSDATE);
END IF;
END;
END;
/
现在使用以下匿名块:
begin
delete from passengerlist1 where flightid = 1;
end;
/
要对passengerlist1表进行一些更改,因为我将此触发器定义为触发器之后的,我希望这些更改首先生效,然后触发器将触发insert到“logs”表中。但是我得到了这个错误:
ORA-04091:表xx_passengerlist1正在突变,触发器/函数可能看不到它
我做错了什么?提前谢谢。您不能在触发器中查询突变表。
见此: 对变异表的触发限制 变异表是一个正在被更新修改的表, DELETE、INSERT语句或可能由 删除级联约束的效果 发出触发语句的会话无法查询或 修改变异表。此限制可防止触发器 看到一组不一致的数据 此限制适用于对每行使用 条款不考虑在而不是触发器中修改的视图 变异 当触发器遇到变异表时,会发生运行时错误, 触发器主体和触发器语句的效果将被滚动 返回,控件将返回给用户或应用程序 请尝试以下代码:
create or replace
TRIGGER log_changes
AFTER INSERT OR UPDATE OR DELETE
ON passengerlist1
FOR EACH ROW
DECLARE
t_name varchar2(255);
t_surname varchar2(255);
BEGIN
IF DELETING THEN
SELECT PERSON1.GIVENNAME, PERSON1.FAMILYNAME INTO T_NAME, T_SURNAME
FROM PERSON1
WHERE PERSON1.PERSONID = :OLD.PERSONID;
INSERT INTO LOGS VALUES (T_NAME, T_SURNAME, :OLD.FLIGHTID, SYSDATE);
END IF;
IF UPDATING OR INSERTING THEN
SELECT PERSON1.GIVENNAME, PERSON1.FAMILYNAME INTO T_NAME, T_SURNAME
FROM PERSON1
WHERE PERSON1.PERSONID = :NEW.PERSONID;
INSERT INTO LOGS VALUES (T_NAME, T_SURNAME, :NEW.FLIGHTID, SYSDATE);
END IF;
END;
/