【发布时间】:2016-02-24 08:22:37
【问题描述】:
我有两个名为 DetailRental 和 Video 的表。 VID_NUM 是 Video 的 PK 和 DetailRental 的 FK。
这段代码想要实现的是,当 DetailRental 表中的 Detail_Returndate 或 Detail_Duedate 发生变化(更新或插入新行)时,触发器将逐行检查 Detail_Returndate 的值。如果其值为空,则视频表中对应的(根据 VID_NUM)属性 VID_STATUS 将更改为“OUT”。
触发器已成功创建。但是,当我想更新日期时。甲骨文给我错误:
ORA-04091: table SYSTEM2.DETAILRENTAL is mutating, trigger/function may not see it
ORA-06512: at "SYSTEM2.TRG_VIDEORENTAL_UP", line 3
ORA-04088: error during execution of trigger 'SYSTEM2.TRG_VIDEORENTAL_UP'
1. UPDATE DETAILRENTAL
2. SET DETAIL_RETURNDATE = null
3. WHERE RENT_NUM = 1006 AND VID_NUM = 61367
下面是我的代码:
CREATE OR REPLACE TRIGGER trg_videorental_up
AFTER INSERT OR UPDATE OF DETAIL_RETURNDATE, DETAIL_DUEDATE ON DETAILRENTAL
FOR EACH ROW
AS
DECLARE
DTRD DATE;
BEGIN
SELECT DETAIL_RETURNDATE
INTO DTRD
FROM DETAILRENTAL;
IF DTRD IS NULL
THEN UPDATE VIDEO
SET VIDEO.VID_STATUS = 'OUT'
WHERE EXISTS
(SELECT DETAILRENTAL.VID_NUM
FROM DETAILRENTAL
WHERE DETAILRENTAL.VID_NUM = VIDEO.VID_NUM
);
END IF;
END;
非常感谢!
这里解决的问题是代码:
CREATE OR REPLACE TRIGGER trg_videorental_up
AFTER INSERT OR UPDATE OF DETAIL_RETURNDATE, DETAIL_DUEDATE ON DETAILRENTAL
FOR EACH ROW
DECLARE DETAIL_RETURNDATE DATE;
BEGIN
IF :NEW.DETAIL_RETURNDATE IS NULL THEN UPDATE VIDEO SET VID_STATUS = 'OUT' WHERE VID_NUM = :NEW.VID_NUM;
ELSIF :NEW.DETAIL_RETURNDATE > SYSDATE THEN UPDATE VIDEO SET VID_STATUS = 'OUT' WHERE VID_NUM = :NEW.VID_NUM;
ELSIF :NEW.DETAIL_RETURNDATE <= SYSDATE AND TO_CHAR(DETAIL_RETURNDATE)!= '01/01/0001' THEN UPDATE VIDEO SET VID_STATUS = 'IN' WHERE VID_NUM = :NEW.VID_NUM;
ELSIF :NEW.DETAIL_RETURNDATE = '01/01/0001' THEN UPDATE VIDEO SET VID_STATUS = 'LOST' WHERE VID_NUM = :NEW.VID_NUM;
END IF;
END;
【问题讨论】:
-
问题已解决。这是代码:
-
这个问题可能是重复的,但是如果风吹错了方向,Oracle 中的突变触发器就会发生。触发器,不知道为什么要这样命名它们,因为它们不是用于事件驱动的编程。当然,您可以更新您的“updated_by”列 - 但除此之外,与 Microsoft SQL Server 相比,它就是一块粪土。
标签: oracle if-statement plsql triggers sql-update