CREATE DEFINER=`ir55`@`%` TRIGGER UpdateAverageBookRating
AFTER INSERT
ON Reviews FOR EACH ROW
BEGIN
DECLARE AverageRating double;
DECLARE lastbookid int;
SELECT BookID FROM Reviews WHERE ReviewID = LAST_INSERT_ID() INTO lastbookid;
SELECT AVG(Rating) FROM Reviews WHERE BookID = lastbookid INTO AverageRating;
UPDATE CentralCatelogue SET Rating = AverageRating WHERE BookID = lastbookid;
END
上述触发器不会更新 CentralCatelogue 中的“Rating”列,因为“Rating”和“BookID”的值为空。
不知道为什么,我尝试用静态值更新评级并且它有效,我相信选择“评论”中的列并将它们分配给变量有问题。
感谢您的帮助。 谢谢
最佳答案
如果您的架构看起来有点像这样
DROP TABLE REVIEWS,CENTRALCATALOGUE;
CREATE TABLE `reviews` (
`bookid` int(11) DEFAULT NULL,
`rating` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `centralcatalogue` (
`bookid` int(11) DEFAULT NULL,
`rating` double(10,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TRIGGER IF EXISTS T;
DELIMITER $$
CREATE TRIGGER `t` AFTER INSERT ON `reviews` FOR EACH ROW BEGIN
DECLARE AverageRating double(10,2);
if not exists (select 1 from centralcatalogue where bookid = new.bookid) then
insert into debug_table(msg) values (concat('inserting:',new.bookid,':',new.rating));
insert into centralcatalogue values(new.bookid,new.rating);
else
SELECT AVG(Rating) FROM Reviews WHERE BookID = new.bookid INTO AverageRating;
insert into debug_table(msg) values (concat('updating',new.bookid,':',averagerating));
UPDATE CentralCatalogue SET Rating = AverageRating WHERE BookID = new.bookid;
end if;
END $$
delimiter ;
注1) 测试并插入以查看centralcatalogue 中是否存在bookid 2) 用于辅助调试的debug_table 3) 将average rating 更改为double(10,2) 以避免向上舍入
插入内容
insert into reviews values(1,1),(1,2),(2,3);
产生
+--------+--------+
| bookid | rating |
+--------+--------+
| 1 | 1.50 |
| 2 | 3.00 |
+--------+--------+
2 rows in set (0.02 sec)
顺便说一句,我不太喜欢这个触发器,因为它会测试并计算每一行。如果将插入和更新封装在事务中可能会更好。
关于mysql触发器不插入选定的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55711635/