MySQL курсор не извлекается внутри процедуры - PullRequest
0 голосов
/ 09 сентября 2011

У меня есть следующие таблицы

альбомы:

+----------------+-------------+------+-----+---------+----------------+
| Field          | Type        | Null | Key | Default | Extra          |
+----------------+-------------+------+-----+---------+----------------+
| album_id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| band_id        | int(11)     | YES  | MUL | NULL    |                |
| release_date   | varchar(45) | YES  |     | NULL    |                |
| name           | varchar(45) | YES  |     | NULL    |                |
| format         | varchar(45) | YES  |     | NULL    |                |
| music_genre_id | int(11)     | YES  | MUL | NULL    |                |
| label_id       | int(11)     | YES  | MUL | NULL    |                |
| avg_rating     | float       | YES  |     | NULL    |                |
+----------------+-------------+------+-----+---------+----------------+

и music_ratings

+-----------------+---------+------+-----+---------+----------------+
| Field           | Type    | Null | Key | Default | Extra          |
+-----------------+---------+------+-----+---------+----------------+
| music_rating_id | int(11) | NO   | PRI | NULL    | auto_increment |
| user_id         | int(11) | YES  | MUL | NULL    |                |
| album_id        | int(11) | YES  | MUL | NULL    |                |
| rating          | int(11) | YES  |     | NULL    |                |
+-----------------+---------+------+-----+---------+----------------+

После каждой вставки в * music_rating * я хочу обновить средний рейтинг в таблице альбомов. У меня есть триггер для этого, который вызывает процедуру. Дело в том, что процедура не работает, по какой-то причине курсор не выбирает данные из таблицы. (Я вызвал процедуру отдельно, чтобы убедиться, что триггер не работает. У таблиц уже есть пара строк, так что это не так.)

Моя процедура довольно проста и выглядит следующим образом

DELIMITER $$

CREATE PROCEDURE avg_album_calc(IN id_album INT)
BEGIN

    DECLARE done INT DEFAULT 0; 
    DECLARE rating INT; 
    DECLARE cur CURSOR FOR SELECT `rating` FROM `music_ratings` WHERE `album_id`=id_album;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

    OPEN cur;   
    SET @ct=0; 
    SET @sm=0;
    REPEAT
        FETCH cur INTO rating;
        IF NOT done
        THEN 
            SET @ct = @ct +1;
            SET @sm = @sm + rating;     
        END IF;

    UNTIL done END REPEAT;
    UPDATE albums SET avg_rating = @sm/@ct WHERE album_id = id_album;
    CLOSE cur;
END$$
DELIMITER ;

Я повторил результат курсора с SELECT rating после команды FETCH cur INTO rating;, и он показывается как ноль.

1 Ответ

0 голосов
/ 09 сентября 2011

Вам не нужно рассчитывать и хранить avg_rating в таблице albums.Вы можете рассчитать на лету -

SELECT a.album_id, a.name, AVG(mr.rating) FROM albums a
  LEFT JOIN music_ratings mr
    ON a.album_id = mr.album_id
GROUP BY a.album_id
...