我有一个名为 [Content] 的SQL表,其中包含以下列:
第一列值是自动生成的。 其余五列值引用名为 [文件]
的表的 ID 列当我从 [内容] 中删除一行时,我还要删除 [文件] 中的行 [File]。[ID] 匹配 [内容]中的值。[文件] , [内容]。[HighResolutionID] 等等。
由于这与多列相关联,级联删除是否有效?如果是这样,语法是什么。
我能想出的最好的结果:
ALTER TABLE [dbo].[File]
ADD CONSTRAINT fk_content_file
FOREIGN KEY (FileID)
REFERENCES [dbo].[File] (ID)
ON DELETE CASCADE;
ALTER TABLE [dbo].[File]
ADD CONSTRAINT fk_content_filehighresolution
FOREIGN KEY (FileHighResolutionID)
REFERENCES [dbo].[File] (ID)
ON DELETE CASCADE;
ALTER TABLE [dbo].[File]
ADD CONSTRAINT fk_content_highresolutionpro
FOREIGN KEY (FileHighResolutionProID)
REFERENCES [dbo].[File] (ID)
ON DELETE CASCADE;
ALTER TABLE [dbo].[File]
ADD CONSTRAINT fk_content_vector
FOREIGN KEY (FileVectorID)
REFERENCES [dbo].[File] (ID)
ON DELETE CASCADE;
ALTER TABLE [dbo].[File]
ADD CONSTRAINT fk_content_thumbnail
FOREIGN KEY (ThumbnailID)
REFERENCES [dbo].[File] (ID)
ON DELETE CASCADE;
...但我不确定这是否正确。到目前为止,我确实比丢失已经填充到应用程序中的数据更明确地知道。
答案 0 :(得分:3)
我认为在你的情况下ON DELETE CASCADE
不是正确的工具。如果你从[Content]
中删除一行,它会删除[File]
中的行,但是我认为你想要反过来。
这可以通过[Content]
上的触发器来实现,但为了确保从[File]
删除行是安全的,您需要检查它是否在其他地方被引用首先是你的[Content]
表(除非你真的,确实确保每个文件只引用一次)。
以下是可以为您执行此操作的触发器示例。请注意,我只在[Content]
表格中实现了几个字段,我相信您可以填写其余字段。
<强>设置强>
Create Table [file] (
FileID int Primary Key Clustered);
Create Table [content] (
ID int,
[File] int Constraint fFile_content References [file] (FileID),
[FileHighResolution] int Constraint fFileHighResolution_content References [file] (FileID));
Insert Into [file] (FileID)
Values (1), (2), (3);
Insert Into [content] (ID, [File], FileHighResolution)
Values (1, 1, 2),
(2, 1, 3);
<强>触发强>
Create Trigger trg_Delete_Remove_Unused_File On [content] After Delete As
Begin
Delete From [file]
From [file] As f
Join Deleted As d
On f.FileID = d.[File]
Where Not Exists (Select 1
From [content]
Where [file] = d.[File]
Or FileHighResolution = d.[File]);
Delete From [file]
From [file] As f
Join Deleted As d
On f.FileID = d.FileHighResolution
Where Not Exists (Select 1
From [content]
Where [file] = d.FileHighResolution
Or FileHighResolution = d.FileHighResolution);
End
之前
FileID
1
2
3
ID File FileHighResolution
1 1 2
2 1 3
<强>验证强>
Delete From [content] Where ID = 1;
后
FileID
1
2
ID File FileHighResolution
2 1 3
文件2已从[File]
表中删除,因为它已从[Content]
AND 中删除的行引用它未被{{1}中的任何其他行引用}}。文件1未从[Content]
中删除,即使它已被删除的行引用,因为它被另一行未被删除引用。
您可能必须针对性能进行优化,但这应该是合乎逻辑的。