обновление нескольких строк в связанной таблице - PullRequest
0 голосов
/ 14 января 2012

Я хотел бы обновить несколько строк столбца 'student_total' в Таблице 'Учитель', когда ученик удален, с использованием триггеров / процедур. Обновление нескольких строк в связанных таблицах, многократные отношения 'n' учителя могут иметь 'м 'студенты

  1. это вообще возможно?потому что невозможно сохранить набор результатов (полученный с вашего сайта)
  2. в Mysql, Postgress и т. д.

Спасибо в Adv

Ритин

--------------- SQL

CREATE TABLE `Teacher` (
  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `student_total` int(11) DEFAULT '0',
  PRIMARY KEY (`id`)
);
CREATE TABLE `Student` (
  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `Teacher_has_Student` (
  `teacher_id` smallint(5) unsigned NOT NULL,
  `student_id` smallint(5) unsigned NOT NULL,
  PRIMARY KEY (`teacher_id`,`student_id`),
  KEY `fk_Teacher_has_Student_teacher` (`teacher_id`),
  KEY `fk_breeder_has_breed_student` (`student_id`),
  CONSTRAINT `fk_Teacher_has_Student_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `Teacher` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `fk_breeder_has_breed_student` FOREIGN KEY (`student_id`) REFERENCES `Student` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

У меня есть триггеры для INSERT / DELETE / UPDATE, например: ---------------------- SQL

CREATE TRIGGER teacher__student_insert AFTER INSERT ON Teacher_has_Student 
FOR EACH ROW 
BEGIN
UPDATE Teacher SET student_total = student_total + 1 WHERE id = NEW.teacher_id;
END;

Триггер, показанный ниже, обновляет только 1 строку, тогда как целью является обновление всех строк.


DELIMITER |
CREATE TRIGGER my_student__delete AFTER DELETE ON Student 
FOR EACH ROW 
BEGIN
set @std_id = old.id;
UPDATE teacher SET student_total = student_total - 1 
WHERE id = @std_id;
END
|

1 Ответ

0 голосов
/ 14 января 2012

Я думаю, что ваш второй триггер не имеет смысла.При удалении ученика вы берете его 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`
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...