我创建了一个包含一些表的数据库,它们彼此相关。但问题是我可以从子表中删除记录,但不能从父表中删除。
请参阅我的SQL表结构代码
User:
CREATE TABLE "User"
(
ID INT generated by default as identity PRIMARY KEY,
username varchar(55) NOT NULL,
password varchar(65) NOT NULL,
"role" varchar(65) NOT NULL
);
Activity:
CREATE TABLE Activity
(
ID INT generated by default as identity PRIMARY KEY,
"time" varchar(55) NOT NULL,
"date" varchar(55) NOT NULL,
purgedDocumentName varchar(55) NOT NULL,
user_ID INTEGER,
CONSTRAINT fk_activity_usr FOREIGN KEY (user_ID)
REFERENCES EDMSDATABASE."User"(ID)
);
Message:
CREATE TABLE Message
(
ID INT generated by default as identity PRIMARY KEY,
title varchar(255) NOT NULL,
subject varchar(255) NOT NULL,
description varchar(255) NOT NULL,
deadline varchar(255) NOT NULL
);
WorkflowMessage:
CREATE TABLE WorkflowMessage
(
user_ID INTEGER ,
message_ID INTEGER ,
CONSTRAINT fk_usr_user FOREIGN KEY (user_ID)
REFERENCES EDMSDATABASE."User"(ID),
CONSTRAINT fk_usr_msg FOREIGN KEY (message_ID)
REFERENCES EDMSDATABASE.Message(ID)
);
Document:
CREATE TABLE Document
(
ID INT generated by default as identity PRIMARY KEY,
"name" varchar(255) NOT NULL,
description varchar(255) NOT NULL,
location varchar(255) NOT NULL,
createdDate varchar(255) NOT NULL,
status varchar(255) NOT NULL,
user_ID INTEGER ,
CONSTRAINT fk_doc_user FOREIGN KEY (user_ID)
REFERENCES EDMSDATABASE."User"(ID)
);
Version:
CREATE TABLE Version
(
ID INT generated by default as identity PRIMARY KEY,
versionNumber INTEGER NOT NULL,
mofiedDate varchar(255) NOT NULL,
newLocation varchar(255) NOT NULL,
document_ID INTEGER ,
CONSTRAINT fk_doc_version FOREIGN KEY (document_ID)
REFERENCES EDMSDATABASE.Document(ID)
);
Trash
CREATE TABLE RemovedDocument
(
ID INTEGER PRIMARY KEY,
FOREIGN KEY (ID) REFERENCES EDMSDATABASE.Document(ID),
newLocation VARCHAR(255)
);
Historical Document
CREATE TABLE HistoricalDocument
(
ID INTEGER PRIMARY KEY,
FOREIGN KEY (ID) REFERENCES EDMSDATABASE.Document(ID),
newLocation VARCHAR(255),
retentionDate VARCHAR(12)
);
Group
CREATE TABLE "Group"
(
"rights" INTEGER NOT NULL,
user_ID INTEGER ,
document_ID INTEGER ,
CONSTRAINT fk_group_document FOREIGN KEY (document_ID)
REFERENCES EDMSDATABASE.DOCUMENT(ID),
CONSTRAINT fk_group_usr FOREIGN KEY (user_ID)
REFERENCES EDMSDATABASE."User"(ID)
);
答案 0 :(得分:3)
您可以从子表中删除行而不是从父表中删除行的原因是,当您在引用主键的子表中添加外键时,您添加到子表的referential integrity在父表中。
例如,为了使用键User
从表ID = 1
中删除行,您首先需要删除下表中外键user_ID = 1
的所有行: / p>
作为手动删除子行的替代方法,您可以做的是使用ON DELETE CASCADE
重新定义外键,即:
CREATE TABLE Activity
(
ID INT generated by default as identity PRIMARY KEY,
... other columns
user_ID INTEGER,
CONSTRAINT fk_activity_usr FOREIGN KEY (user_ID)
REFERENCES EDMSDATABASE."User"(ID) ON DELETE CASCADE -- Cascading delete
);
这里会发生的是,如果删除了引用的父User.ID
行,则删除表Activity
中链接的所有子行。 (您需要对引用User.Id
的所有子表重复上述操作。)谨慎使用此选项!
另一种方法是允许外键在子表中为null,然后在外键中指定ON DELETE SET NULL
:
CREATE TABLE Activity
(
ID INT generated by default as identity PRIMARY KEY,
... other columns
user_ID INTEGER NULL, -- Nullable
CONSTRAINT fk_activity_usr FOREIGN KEY (user_ID)
REFERENCES EDMSDATABASE."User"(ID) ON DELETE SET NULL
);
与级联删除一样,如果删除了父User.Id
行,则Activity
中的所有引用子行都会将UserId
更新为NULL(但不会删除)。同样,要小心这种方法,因为这会导致子行成为孤儿。