为什么 SQL 在删除引用时无法删除父行
why SQL cannot delete parent row when references are deleted
我创建了一个包含一些 table 的数据库,它们相互关联。但问题是我可以从子 table 中删除记录,但不能从父 table.
中删除记录
查看我的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)
);
您可以从子 table 中删除行但不能从父 table 中删除行的原因是您添加到子 [=48] 的 referential integrity =]s 当您在子 tables 中添加外键时引用父 tables.
中的主键
例如,要从 table User
中删除带有键 ID = 1
的行,您首先需要删除外键 user_ID = 1
所在的所有行在接下来的 table 中:
- Activity
- 工作流消息
- 文档
- 组
作为手动删除子行的替代方法,您可以使用 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
行被删除,则 table Activity
中链接的所有子行都将被删除。 (您需要为所有引用 User.Id
的子 table 重复上述操作)请谨慎使用此选项!
另一种方法是在子table中允许外键为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(但未删除) .同样,请谨慎使用这种方法,因为这会导致子行成为孤立行。
我创建了一个包含一些 table 的数据库,它们相互关联。但问题是我可以从子 table 中删除记录,但不能从父 table.
中删除记录查看我的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)
);
您可以从子 table 中删除行但不能从父 table 中删除行的原因是您添加到子 [=48] 的 referential integrity =]s 当您在子 tables 中添加外键时引用父 tables.
中的主键例如,要从 table User
中删除带有键 ID = 1
的行,您首先需要删除外键 user_ID = 1
所在的所有行在接下来的 table 中:
- Activity
- 工作流消息
- 文档
- 组
作为手动删除子行的替代方法,您可以使用 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
行被删除,则 table Activity
中链接的所有子行都将被删除。 (您需要为所有引用 User.Id
的子 table 重复上述操作)请谨慎使用此选项!
另一种方法是在子table中允许外键为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(但未删除) .同样,请谨慎使用这种方法,因为这会导致子行成为孤立行。