2016-12-05 5 views
2

У меня есть таблица SQL называется [Content], которая имеет столбцы, как:SQL Каскадное удаление с несколькими столбцами

  • ID PrimaryKey, UniqueIdentifier, не нулевой
  • Файл UniqueIdentifier, не нулевой
  • FileHighResolutionID uniqueidentifier, not null
  • FileHighRe solutionProID UniqueIdentifier, а не нулевой
  • FileVectorID UniqueIdentifier, а не нулевой
  • ThumbnailID UniqueIdentifier, а не нулевой

Первое значение столбца автоматически сгенерированный. Остальные пять значений столбцов ссылаться на ID столбец таблицы называется [Файл]

При удалении строки из [Содержание], Я хотел бы также удалить строки из [Файл], где [Файл]. [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

FWIW, я использую хранимую процедуру для такого рода вещей. Это усложняет мне выполнение чего-то невероятно глупого, и при этом он легко каскадирует данные, он позволяет проверять дополнительные критерии, пользователям может быть предоставлен доступ к SP без доступа к базовым таблицам, SP может выполнять дополнительную регистрацию. ... – HABO

ответ

2

Я думаю, что в вашей ситуации 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); 

Trigger

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]И он не ссылается какой-либо другая строка в [Content]. Файл 1 не удалялся из [File], хотя на него ссылалась удаленная строка, потому что на нее ссылалась другая строка, которая не была удалена.

Возможно, вам придется оптимизировать это для производительности, но это должно быть логически обоснованным.

+0

Обратите внимание, что я по-прежнему добавил ограничения ссылочной целостности на свой стол, и вам тоже нужно. – mendosi

+0

Удивительный! Я попробую это утром, когда я войду в офис. –

+0

Просто пытаюсь следовать. Действительно ли условие ИЛИ во внутреннем выборе действительно необходимо? В моем случае столбцы FileHighResolutionID и FileID никогда не могут быть привязаны к той же строке в файле (с точки зрения приложения). –