所以我必须创建一个触发器,它将对名为'passengerlist1'的表所做的更改记录到一个名为'logs'的额外表中。
日志表:
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。这是我需要选择一个人的给定名称和姓氏并将其存储到'logs'表,以防对'passengerlist1'表进行更改。从'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表进行一些更改,因为我将此触发器定义为 AFTER 触发器,我希望更改首先生效,然后触发器会触发插入'logs'表。但相反,我得到了这个错误:
ORA-04091:表格xx_passengerlist1正在变异,触发/功能可能看不到它
我做错了什么?提前谢谢。
答案 0 :(得分:3)
您无法在触发器中查询变异表 看到这个: https://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm
对变异表的触发限制
变异表是由UPDATE修改的表, DELETE,或INSERT语句,或者可能由更新的表 DELETE CASCADE约束的效果。
发出触发语句的会话无法查询或 修改变异表。此限制可防止触发器发生 看到一组不一致的数据。
此限制适用于使用FOR EACH ROW的所有触发器 条款。不考虑在INSTEAD OF触发器中修改的视图 突变。
当触发器遇到变异表时,会发生运行时错误, 滚动触发器主体和触发语句的效果 返回,并将控制权返回给用户或应用程序。
请尝试使用此代码:
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;
/