Я думаю, что ваш второй триггер не имеет смысла.При удалении ученика вы берете его id
и уменьшаете student_total
учителя, у которого случайно тот же id
, что и у студента.
Ваше определение плюс первый триггер уже должнысделать работу.Если вы удаляете ученика, его отношения удаляются из Teacher_has_Student
с помощью CASCADE
, и на этом DELETE
ваши триггеры должны срабатывать , чтобы уменьшить student_total
затронутых учителей.В любом случае, небольшое исследование Google показывает, что MySQL, очевидно, не запускает триггеры при каскадном удалении:
http://bugs.mysql.com/bug.php?id=13102
Возможные обходные пути
Youможет попытаться исправить ваш второй триггер, чтобы выполнить работу вручную:
DELIMITER |
CREATE TRIGGER my_student__delete AFTER DELETE ON Student
FOR EACH ROW
BEGIN
SET @std_id = old.`id`;
UPDATE
`Teacher` AS T
INNER JOIN `Teacher_has_Student` AS TS ON T.`id`=TS.`teacher_id`
SET `student_total` = `student_total` - 1
WHERE ST.`student_id` = @std_id;
END
|
Но это не сработает, если CASCADE
на FOREIGN KEY
выполняется перед вашим триггером.
Возможно, более надежный обходной путь - сбросить определения FOREIGN KEY
и создать триггеры на Teacher
и Student
для каскадного удаления и обновления до Teacher_has_Student
.
Нормализовать его
С обходными путями вы должны иметь в виду множество различных сценариев, чтобы student_total
действовал.Если нет необходимости хранить student_total
непосредственно на Учительском столе, я настоятельно рекомендую не делать этого.
Информация абсолютно избыточна.Сохраните ограничения и каскады, но опустите столбец student_total
и удалите все триггеры.Затем используйте JOIN, чтобы получить номера своих студентов:
SELECT
T.`id`, T.`name`, COUNT(*) AS student_total
FROM `Teacher` AS T
INNER JOIN `Teacher_has_Student` AS TS ON T.`id`=TS.`teacher_id`
GROUP BY T.`id`