sql >> Databáze >  >> RDS >> Mysql

Cizí klíč s více sloupci:Nastavte jeden sloupec na hodnotu Null ON DELETE namísto všech

Po nějakém výzkumu se zdá, že tento konkrétní požadavek nelze implementovat pomocí cizích klíčů.

Nejlepším řešením se zdá být použití kombinace cizích klíčů a spouštěč .

Problém lze pro daný příklad vyřešit následujícími výroky:

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;

Všimněte si, že "ON DELETE CASCADE" posledního cizího klíče nikdy nepovede ke kaskádovému odstranění, protože Trigger již odstranil odkazy na cizí klíč zrušením hodnoty null v odpovídajících řádcích.

Dodatek:Místo použití „ON DELETE CASCADE“ lze použít „ON DELETE SET NULL“ se stejným spouštěčem, ale pak „lectureId“ musí mít hodnotu null a jeden by měl obsahovat „CHECK (lectureId IS NOT NULL)“ abyste zajistili, že nebude nikdy nastaven na hodnotu null




  1. Pozor uživatelé používající SQL Server 2008 a SQL Server 2008 R2

  2. java.lang.IllegalArgumentException:sloupec '_id' neexistuje

  3. Drop database return Chyba při shazování databáze errno:66 v MySQL

  4. Jak vyprázdnit všechny řádky ze všech tabulek v mysql (v sql)