SQL Cascade删除多列

时间:2016-12-05 23:27:38

标签: sql-server tsql sql-server-2014

我有一个名为 [Content] 的SQL表,其中包含以下列:

  • ID PrimaryKey,uniqueidentifier,not null
  • 文件 uniqueidentifier,非null
  • FileHighResolutionID uniqueidentifier,非null
  • FileHighResolutionProID uniqueidentifier,非null
  • FileVectorID uniqueidentifier,非null
  • ThumbnailID uniqueidentifier,非null

第一列值是自动生成的。 其余五列值引用名为 [文件]

的表的 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;

...但我不确定这是否正确。到目前为止,我确实比丢失已经填充到应用程序中的数据更明确地知道。

1 个答案:

答案 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]中删除,即使它已被删除的行引用,因为它被另一行未被删除引用。

您可能必须针对性能进行优化,但这应该是合乎逻辑的。