我将尝试解释我的问题,与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
我几乎可以肯定它,因为在另一个触发器中出现相同的“问题”。好吧,我希望以自动的方式“避免”这个结构问题,在插入或更新之后创建一个“方法”来进行计算,但是真的插入那一行。
我该怎么做?
答案 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
,但我不认为这是一个很好的解决方案:如果您在主要事务中回滚更改,则会提交触发器内的更新。除此之外,如果您只计算笔记的平均值,那么分组并不是真正必要的。