SQL ПРИ ИЗТРИВАНЕ НА КАСКАДА, по какъв начин става изтриването?

Ако имам две релации в база данни, като това:

CREATE TABLE Courses (
  CourseID int NOT NULL PRIMARY KEY,
  Course VARCHAR(63) NOT NULL UNIQUE,
  Code CHAR(4) NOT NULL UNIQUE
);

CREATE TABLE BookCourses (
  EntryID int NOT NULL PRIMARY KEY,
  BookID int NOT NULL,
  Course CHAR(4) NOT NULL,
  CourseNum CHAR(3) NOT NULL,
  CourseSec CHAR(1) NOT NULL
);

и установявам връзка с външен ключ между двете, като тази:

ALTER TABLE BookCourses
ADD FOREIGN KEY (Course)
REFERENCES Courses(Code)
ON DELETE CASCADE;

Тогава можете да видите, че атрибутът Course в релацията BookCourses препраща към атрибута Code в релацията Courses.

Въпросът ми е, когато настъпи изтриване в някоя от двете релации, по какъв начин се извършва каскадата на изтриването? Ако изтрия кортеж в релацията Courses, ще изтрие ли всички препращащи кортежи в релацията BookCourses, или е обратното?


person Oliver Spryn    schedule 18.11.2012    source източник
comment
Човек само се чуди защо таблицата Categories има CourseID като първичен ключ, докато таблицата Courses има EntryID. Сериозно трябва да преосмислите избора си за име.   -  person ypercubeᵀᴹ    schedule 19.11.2012
comment
Моля, използвайте правилните имена на колони, за да избегнете объркване и да изчистите структурата на DB.   -  person Gunjan Shah    schedule 22.03.2013


Отговори (2)


Каскадата ще работи, когато изтриете нещо в таблица Courses. Всеки запис в таблица BookCourses, който има препратка към таблица Courses, ще бъде изтрит автоматично.

Но когато се опитате да изтриете на таблица BookCourses само самата таблица е засегната, а не на Courses

допълнителен въпрос: защо имате CourseID в категорията на масата?

Може би трябва да преструктурирате вашата схема в това,

CREATE TABLE Categories 
(
  Code CHAR(4) NOT NULL PRIMARY KEY,
  CategoryName VARCHAR(63) NOT NULL UNIQUE
);

CREATE TABLE Courses 
(
  CourseID INT NOT NULL PRIMARY KEY,
  BookID INT NOT NULL,
  CatCode CHAR(4) NOT NULL,
  CourseNum CHAR(3) NOT NULL,
  CourseSec CHAR(1) NOT NULL,
);

ALTER TABLE Courses
ADD FOREIGN KEY (CatCode)
REFERENCES Categories(Code)
ON DELETE CASCADE;
person John Woo    schedule 18.11.2012
comment
Този отговор има различни имена на таблици и структури от въпроса... Правейки го много по-малко полезен. - person Daniel Beardsley; 14.05.2013
comment
@DanielBeardsley, не съм съгласен, че този отговор не е полезен. Това е, ако прочетете какво пише. Съгласен съм обаче, че отговорът може да бъде форматиран, така че да е ясно какво е част от действителния отговор и какво е друга дискусия. Подчертаната по-горе схема е свързана с допълнителния въпрос, но не и отговора на действителния въпрос. - person Baldur; 22.01.2016

Ето прост пример за други, които посещават тази стара публикация, но са объркани от примера във въпроса и другия отговор:

Доставка -› Пакет (Един -› Много)

CREATE TABLE Delivery(
    Id INT IDENTITY PRIMARY KEY,
    NoteNumber NVARCHAR(255) NOT NULL
)

CREATE TABLE Package(
    Id INT IDENTITY PRIMARY KEY,
    Status INT NOT NULL DEFAULT 0,
    Delivery_Id INT NOT NULL,
    CONSTRAINT FK_Package_Delivery_Id FOREIGN KEY (Delivery_Id) REFERENCES Delivery (Id) ON DELETE CASCADE
)

Записът с външния ключ Delivery_Id (Package) се изтрива с референтния обект във връзката FK (Delivery).

Така че, когато една Доставка бъде изтрита, Пакетите, които я препращат, също ще бъдат изтрити. Ако даден пакет бъде изтрит, нищо не се случва с никакви доставки.

person Morten Holmgaard    schedule 22.08.2018