SQL ON DELETE CASCADE, de que maneira a exclusão ocorre?

156

Se eu tiver duas relações em um banco de dados, assim:

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
);

e eu estabeleço um relacionamento de chave estrangeira entre os dois, assim:

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

Então você pode ver que o Courseatributo na BookCoursesrelação faz referência ao Codeatributo na Coursesrelação.

Minha pergunta é quando ocorre uma exclusão em qualquer uma das duas relações. De que maneira a exclusão é em cascata? Se eu excluir uma tupla na Coursesrelação, ela excluirá todas as tuplas de referência na BookCoursesrelação ou será o contrário?

Oliver Spryn
fonte
11
Só se pergunta por que a Categoriestabela possui a CourseIDcomo Chave Primária enquanto a Coursestabela possui o EntryID. Você realmente precisa repensar suas opções de nomes.
ypercubeᵀᴹ
7
Por favor, use nomes de colunas apropriados para evitar confusão e limpar a estrutura do banco de dados.
Gunjan Shah

Respostas:

185

O Cascade funcionará quando você excluir algo da tabela Courses. Qualquer registro na tabela BookCoursesque tenha referência à tabela Coursesserá excluído automaticamente.

Mas quando você tenta excluir na tabela, BookCoursesapenas a tabela em si é afetada e não noCourses

pergunta de acompanhamento: por que você tem CourseIDna tabela Categoria?

Talvez você deva reestruturar seu esquema para isso,

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;
John Woo
fonte
5
Ótimo! Obrigado. resposta de acompanhamento: Porque eu pensei demais. Corrigido agora ... e no meu banco de dados
Oliver Spryn 18/11/2012
59
Essa resposta tem nomes e estruturas de tabela diferentes da pergunta ... Tornando-a muito menos útil.
Daniel Beardsley
4
@DanielBeardsley, eu não concordo que esta resposta não seja útil. Ou seja, se você ler o que diz. No entanto, concordo que a resposta possa ser formatada, para que fique claro o que faz parte da resposta real e o que é outra discussão. O esquema destacado acima está relacionado à pergunta de acompanhamento, mas não à resposta à pergunta real.
Baldur
26

Aqui está um exemplo simples para outras pessoas que visitam esse post antigo, mas está confuso com o exemplo da pergunta:

Entrega -> Pacote (Um -> Muitos)

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
)

A entrada com a chave estrangeira Delivery_Id (Package) é excluída com a entidade referenciada no relacionamento FK (Delivery).

Portanto, quando uma Entrega é excluída, os Pacotes referenciados também serão excluídos. Se um pacote for excluído, nada acontece com as entregas.

Morten Holmgaard
fonte
Obrigado pelo exemplo fácil de entender!
Tom Spencer