Na wat onderzoek lijkt het erop dat die specifieke vereiste niet kan worden geïmplementeerd met behulp van externe sleutels.
De beste oplossing lijkt het gebruik van een mix van Foreign Keys en een Trigger .
Het probleem kan voor het gegeven voorbeeld worden opgelost door de volgende uitspraken:
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;
Houd er rekening mee dat de "ON DELETE CASCADE" van de laatste externe sleutel nooit zal leiden tot een trapsgewijze verwijdering, aangezien de trigger de verwijzingen van de externe sleutel al heeft verwijderd door de bijbehorende rijen null te geven.
Toevoeging:in plaats van "ON DELETE CASCADE" te gebruiken, zou men "ON DELETE SET NULL" kunnen gebruiken met dezelfde trigger, maar dan moet "lectureId" nullable zijn en moet er een "CHECK (lectureId IS NOT NULL)" zijn om ervoor te zorgen dat het nooit op null staat