PL SQL:使用AFTER INSERT在TRIGGER中插入缺少的行

时间:2014-07-29 13:53:27

标签: sql oracle plsql triggers

我将尝试解释我的问题,与Trigger功能相关联。我想在表中添加一行,将注意力集中在列中的特定数字,称为“VOTO”(VOTE),例如:

ID  UTENTE_ID  DATA       COMMENTO     ISBN            VOTO
50  423573     29-LUG-14  CAPOLAVORO!  9788804508359   5

插入后,它将激活一个触发器,如下所示:

create or replace TRIGGER CREATE_COMMENT
AFTER INSERT OR UPDATE ON RECENSIONI
FOR EACH ROW

pragma autonomous_transaction;

BEGIN
    UPDATE LIBRI
    SET VOTOPROD_MEDIA=(SELECT AVG(VOTO) FROM RECENSIONI WHERE ISBN=:NEW.ISBN GROUP BY ISBN)
    WHERE ISBN=:NEW.ISBN;

END;

这个触发器背后的想法在这里解释:我必须添加一个带有VOTE的行,然后,它将被选择一行到另一个名为LIBRI(books)的表中,其中包含一个名为VOTOPROD_MEDIA的参数(一本书的平均费率)将存储与该书相关的评论的所有投票的平均费率(AVG)。

触发前的例子:

表评论:

ID  USER_ID  DATE       COMMENT     ISBN            VOTE
50  423573   29-LUG-14  CAPOLAVORO! 9788804508359   5

表格书:

ISBN           AVERAGE_VOTE
9788804508359  5

触发后我会做什么的例子:

表评论:

ID  USER_ID  DATE       COMMENT     ISBN            VOTE
50  423573   29-LUG-14  CAPOLAVORO! 9788804508359   5
51  423574   29-LUG-14  BAD BOOK!   9788804508359   1

表格书:

ISBN           AVERAGE_VOTE
9788804508359  3

3是“AVG”值5和1。

不幸的是,它不起作用。最后一次插入似乎不会影响该更新。事实上,虽然执行此触发表COMMENTS,我想,尚未更新插入新行,因此,当它尝试制作AVG时,表书中的投票保持为5,而不是更改为3

即使我使用“AFTER INSERT”,我认为在触发期间,“RECENSIONI”表仍然处于这种状态:

ID  USER_ID  DATE       COMMENT     ISBN            VOTE
50  423573   29-LUG-14  CAPOLAVORO! 9788804508359   5

我几乎可以肯定它,因为在另一个触发器中出现相同的“问题”。好吧,我希望以自动的方式“避免”这个结构问题,在插入或更新之后创建一个“方法”来进行计算,但是真的插入那一行。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

您可以使用以下内容创建简单视图:

CREATE OR REPLACE VIEW V_LIBRI AS
SELECT L.ISBN, AVG(R.VOTO) AS VOTO_MEDIO
FROM LIBRI L
LEFT JOIN RECENSIONI R
ON R.ISBN = L.ISBN
GROUP BY L.ISBN;

SQL Fiddle演示。无需触发器。对于视图效果不佳的大量数据,您可能会考虑使用物化视图,但这样做会有利有弊(例如需要更多存储空间)。

答案 1 :(得分:0)

首先,您在触发器COMMIT之前错过了END;。其次,您想使用AUTONOMOUS_TRANSACTION PRAGMA,但我不认为这是一个很好的解决方案:如果您在主要事务中回滚更改,则会提交触发器内的更新。除此之外,如果您只计算笔记的平均值,那么分组并不是真正必要的。