0

我创建了一个触发器,Payment当向表中插入新记录时,它将更新表(用于账单)Enrollment。我的触发器如下:

CREATE OR REPLACE TRIGGER EnrollFee_trig
AFTER INSERT ON Enrollment
FOR EACH ROW

DECLARE
amount Payment.TotalPrice%TYPE;
id Payment.LearnerID%TYPE;

BEGIN
SELECT SUM(Price) into amount
FROM LearnerEnrollCourse_View
WHERE LearnerID = :NEW.LearnerID
AND Paid = 'N';

SELECT LearnerID into id
FROM Payment
WHERE LearnerID = :NEW.LearnerID
AND PaymentDate IS NULL;

IF SQL%FOUND THEN
UPDATE Payment 
SET TotalPrice = amount 
WHERE LearnerID = :new.LearnerID
    AND PaymentDate IS NULL;
ELSE  
INSERT INTO Payment VALUES
     (PaymentID_Seq.nextval, :new.LearnerID, '', amount);  
END IF;

END;
/

可以成功创建触发器。但是在插入新记录时Enrollment,出现“表ENROLLMENT正在变异,触发器/函数可能看不到它”的错误。我想更具体地了解导致此问题的原因以及如何解决。

4

1 回答 1

2

当我们尝试从行级触发器代码中引用查询中的触发表时,会发生变异表异常。在这里查看更多

在这种情况下,我怀疑(尽管我不知道 LearnerEnrollCourse_View 没有定义)问题是由以下语句引起的:-

SELECT SUM(Price) into amount
FROM LearnerEnrollCourse_View
WHERE LearnerID = :NEW.LearnerID
AND Paid = 'N';

如果 LearnerEnrollCourse_view 视图引用 Enrollment 表,您将收到 mutating table 错误。有很多方法可以解决它,将触发器代码移动到语句级触发器并将数据保存在包变量中是一种解决方法,但总的来说,我认为使用触发器不是最好的方法,触发器越多你有,你就越有可能遇到这个问题和其他问题。相反,我将有一个用于注册表的 api 包,并将触发代码移到那里。

在这里很好地讨论了触发器

于 2013-07-18T12:57:40.223 回答