Каскадное удаление в SQL Sever 2008 не работает - PullRequest
0 голосов
/ 18 марта 2010

У меня есть следующие настройки таблицы.

Bag
  |
  +-> BagID (Guid)
  +-> BagNumber (Int)

BagCommentRelation
  |
  +-> BagID (Int)
  +-> CommentID (Guid)

BagComment
  |
  +-> CommentID (Guid)
  +-> Text (varchar(200))

BagCommentRelation имеет внешние ключи для Bag и BagComment.

Итак, я включил каскадное удаление для обоих этих внешних ключей, но когда я удаляю пакет, он не удаляет строку «Комментарий».

Нужно ли спустить курок для этого? Или я что-то упустил?

(я использую SQL Server 2008)


Примечание: отправка запрошенного SQL. Это определение таблицы BagCommentRelation. (У меня был неправильный тип bagID (я думал, что это guid, но это int).)

CREATE TABLE [dbo].[Bag_CommentRelation](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [BagId] [int] NOT NULL,
    [Sequence] [int] NOT NULL,
    [CommentId] [int] NOT NULL,
 CONSTRAINT [PK_Bag_CommentRelation] PRIMARY KEY CLUSTERED 
(
    [BagId] ASC,
    [Sequence] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[Bag_CommentRelation]  WITH CHECK ADD  CONSTRAINT [FK_Bag_CommentRelation_Bag] FOREIGN KEY([BagId])
REFERENCES [dbo].[Bag] ([Id])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[Bag_CommentRelation] CHECK CONSTRAINT [FK_Bag_CommentRelation_Bag]
GO

ALTER TABLE [dbo].[Bag_CommentRelation]  WITH CHECK ADD  CONSTRAINT [FK_Bag_CommentRelation_Comment] FOREIGN KEY([CommentId])
REFERENCES [dbo].[Comment] ([CommentId])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[Bag_CommentRelation] CHECK CONSTRAINT [FK_Bag_CommentRelation_Comment]
GO

Строка в этой таблице удаляется, а строка в таблице комментариев - нет.

Ответы [ 3 ]

1 голос
/ 18 марта 2010

Ваша таблица BagCommentRelation имеет отношение n: m между Bag и BagComments, поэтому она является подробной таблицей для обеих других таблиц.

Ограничение DELETE CASCADE будет работать только с таблицей сведений, поэтому однозначно BagComment нельзя удалить, если Bag удален.

Что заставляет меня задуматься, как комментарий к сумке можно применить к нескольким сумкам.

Если вам действительно нужно иметь один и тот же BagComment, используемый для разных записей Bag, я предлагаю триггер DELETE для Bag_CommentRelation, который удаляет все BagComments, на которые больше не ссылается таблица отношений.

1 голос
/ 18 марта 2010

Лично я бы вообще не использовал каскадное удаление. Что если понадобится большая группа сумок? Каскадное удаление может связывать ваши таблицы часами. Лучше специально писать нужные удаления.

1 голос
/ 18 марта 2010

С вашей текущей структурой запись BagComment не будет удалена при удалении Bag, только записи BagCommentRelation. Удаление каскадируется от Bag до BagCommentRelation, но на этом останавливается. Ваша структура выглядит как отношение «многие ко многим» между Bag и BagCommentRelation. Зачем вам нужно BagCommentRelation?

Редактировать: Похоже, проще всего было бы сделать вашу структуру такой:

Bag 
  | 
  +-> BagID (Guid)
  +-> BagNumber (Int)

BagComment 
  | 
  +-> BagID (Guid)
  +-> Text (varchar(200))

, но использование таблицы BagComment (или Comment) для ссылки на несколько объектов добавляет некоторую сложность. Если это то, что вам нужно сделать, этот вопрос должен оказать помощь.

...