След известно проучване изглежда, че това конкретно изискване не е приложимо с помощта на външни ключове.
Най-доброто решение изглежда е използването на микс от външни ключове и Задействане .
Проблемът може да бъде решен за дадения пример със следните твърдения:
CREATE TABLE lectures (
lectureId INT NOT NULL,
title VARCHAR(10) NOT NULL,
PRIMARY KEY (lectureId)
);
CREATE TABLE groups (
lectureId INT NOT NULL,
groupNo INT NOT NULL,
title VARCHAR(10) NOT NULL,
PRIMARY KEY (lectureId,groupNo),
FOREIGN KEY (lectureId) REFERENCES lectures (lectureId)
ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE studentListed (
studentId INT NOT NULL,
lectureId INT NOT NULL,
groupNo INT NULL,
PRIMARY KEY (studentId,lectureId),
FOREIGN KEY (lectureId) REFERENCES lectures (lectureId)
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (lectureId,groupNo) REFERENCES groups (lectureId,groupNo)
ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TRIGGER GroupDelete BEFORE DELETE ON groups
FOR EACH ROW
UPDATE studentListed SET studentListed.groupNo = NULL
WHERE studentListed.lectureId = OLD.lectureId
AND studentListed.groupNo = OLD.groupNo;
Имайте предвид, че „ON DELETE CASCADE“ на последния външен ключ никога няма да доведе до каскадно изтриване, тъй като тригерът вече е премахнал препратките към външния ключ чрез нулиране на съответните редове.
Допълнение:Вместо да се използва „ON DELETE CASCADE“ може да се използва „ON DELETE SET NULL“ със същия тригер, но тогава „lectureId“ трябва да бъде нула и трябва да се включва „CHECK (lectureId IS NOT NULL)“ за да се гарантира, че никога не е настроен на null