Mysql
 sql >> Base de données >  >> RDS >> Mysql

Clé étrangère à plusieurs colonnes :définissez une seule colonne sur Null ON DELETE au lieu de toutes

Après quelques recherches, il semble que cette exigence particulière ne soit pas implémentable à l'aide de clés étrangères.

La meilleure solution semble être d'utiliser un mélange de clés étrangères et un déclencheur .

Le problème peut être résolu pour l'exemple donné par les instructions suivantes :

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;

Notez que "ON DELETE CASCADE" de la dernière clé étrangère ne conduira jamais à une suppression en cascade car le déclencheur a déjà supprimé les références de clé étrangère en annulant les lignes correspondantes.

Ajout :Au lieu d'utiliser "ON DELETE CASCADE", on peut utiliser "ON DELETE SET NULL" avec le même déclencheur, mais alors "lectureId" doit être nullable et il faut inclure un "CHECK (lectureId IS NOT NULL)" pour s'assurer qu'il n'est jamais défini sur null