首页 > 解决方案 > Round() 函数在触发器内部的工作方式是否不同?

问题描述

我正在做一个教育项目,我必须创建一个电子商店。我正在使用 mysql 来构建我的数据库。我有 3 个表 A."books" B."users" C."REVIEWS"。REVIEWS 表有一个id作为主键、user_id作为外键和book_id作为外键的名为的列comments,用于保存用户的评论,而列 rating 用于保存用户对一本书的评分。在 book 表中,我有一个名为 total_rating 的字段,用于保存书评的总评分。我想创建一个触发器,在插入评论表后更新总评分和评分数(书籍表中的列)。

CREATE TABLE `books` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `ISBN` char(13) NOT NULL,
  `No_of_pages` varchar(6) NOT NULL,
  `description` text,
  `regular_price` decimal(5,2) NOT NULL,
  `store_quantity` int DEFAULT NULL,
  `image` blob,
  `total_rating` decimal(2,1) DEFAULT NULL,
  `count_reviews` int DEFAULT NULL,
  `count_sales` int DEFAULT NULL,
  `author_id` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `books_author_id_authors_id_fk` (`author_id`),
  CONSTRAINT `books_author_id_authors_id_fk` FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `reviews` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_id` int NOT NULL,
  `book_id` int NOT NULL,
  `rating` decimal(2,1) DEFAULT NULL,
  `review_datetime` datetime NOT NULL,
  `comment` varchar(400) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `combined_user_book` (`user_id`,`book_id`),
  KEY `reviews_user_id_users_id_fk_idx` (`user_id`),
  KEY `reviews_book_id_books_id_fk_idx` (`book_id`),
  CONSTRAINT `reviews_book_id_books_id_fk` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`),
  CONSTRAINT `reviews_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

所以我做了这个触发器

DELIMITER //
CREATE TRIGGER tr_insert_reviews
AFTER INSERT
ON `reviews` FOR EACH ROW
BEGIN
DECLARE bookid int;
DECLARE lastid int;
DECLARE aveg int;
DECLARE reviews_number int;
SELECT id FROM reviews ORDER BY id DESC LIMIT 1 into lastid; 
SELECT book_id FROM reviews WHERE id = lastid into bookid;
SELECT ROUND(AVG(rating),1) FROM reviews WHERE book_id = bookid into aveg;
SELECT COUNT(rating) FROM reviews WHERE book_id = bookid into reviews_number;
UPDATE books SET total_rating = aveg, count_reviews = reviews_number WHERE id = bookid;
END //
DELIMITER ;

触发器有效,但不保留结果的精确小数,而是将小数四舍五入为零。例如,不是给出真实结果的 3.9,而是将其四舍五入为 4.0。当我在触发器之外执行此操作时,它会正常保留小数. 你知道我该如何解决这个问题吗?另外,我不确定在评论表中插入后创建一个触发器来自动计算 total_rating 是否是个好主意。我认为这样会更好,以免在后端进行此过程(java rest api 项目)。你怎么看?最后但并非最不重要的一点是,无论如何要告诉触发器在删除/更新之后或之前运行并获取已删除/更新行的 id?

很抱歉有多个问题,我对编程真的很陌生,问题在我脑海中呈指数级增长。提前致谢!

标签: mysqltriggers

解决方案


推荐阅读