SQL Server 2008 - несколько каскадных FK - мне нужен триггер? - PullRequest
5 голосов
/ 24 февраля 2011

У меня 1 .. * отношение между Пользователь и Пост .(у одного пользователя много сообщений)

В сообщении есть FK с именем "UserId", который отображается в поле "UserId" в таблице User .

Я пытался установить этот FK как Cascade UPDATE / DELETE, но я получаю эту ошибку:

Таблица пользователей успешно сохранена. Таблица сообщений - Невозможно создать связь FK_Posts_Users.
Введение ограничения FOREIGN KEY 'FK_Posts_Users' в таблицу 'Posts' может привести к циклам или нескольким каскадным путям.Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION, либо измените другие ограничения FOREIGN KEY.Не удалось создать ограничение.См. Предыдущие ошибки.

У меня есть таблица с именем PostHelpful. В одном сообщении много полезных.

У полезного есть каскадный FK для пользователя (например, когда пользовательудаляются, их полезные сообщения также удаляются).

Но я думаю, что это является причиной жалобы на "несколько каскадных путей".

Потому что, если я удаляю пользователя (в настоящее время), он будетудалите их полезности.Но я пытаюсь также добавить каскад в сообщение, сделайте так, чтобы оно удалило сообщение, затем попытайтесь удалить полезные для этого сообщения (поскольку у полезного также есть каскадный FK для публикации).В этом сценарии какой каскадный FK выберет SQL?

Вот диаграмма базы данных трех рассматриваемых таблиц:

enter image description here

Как видите, "PostHelpful "является дочерним по отношению к" Post "и" User "(имеет FK для обоих).

То есть я не могу сделать оба ключа каскадными?Нужен ли мне триггер для «Пользователи» (ПОСЛЕ УДАЛЕНИЯ), чтобы вручную удалить подсказки (и другие таблицы, ссылающиеся на Пользователя).

1 Ответ

3 голосов
/ 02 марта 2011

Вопрос не в том, какой путь выберет SQL Server, он не допускает его, чтобы он не оказался в компромиссном положении.Когда мы столкнулись с этой ситуацией, нам пришлось прибегнуть к курку.

1) Как указано в сообщении об ошибке, измените Users_PostHelpfuls FK на ON УДАЛИТЬ, НЕТ ДЕЙСТВИЯ .

2) Добавить INSTEADOF DELETE триггер для пользователей:

CREATE TRIGGER dbo.Users_IO_Delete 
ON dbo.Users
INSTEAD OF DELETE
AS
BEGIN;
    DELETE FROM dbo.PostHelpfuls WHERE UserId IN (SELECT UserId FROM deleted);

    DELETE FROM dbo.Users WHERE UserId IN (SELECT UserId FROM deleted);
END;

Теперь FK по-прежнему будет принудительно использовать DRI, но триггер каскадно удаляет, а не ограничение FK.

Вы можете заменить PostHelpfuls с Сообщений в вышеуказанных шагах.Но при этом лучше всего использовать триггер, чтобы удалить записи менее независимого объекта.Другими словами, более вероятно, что сообщений связаны с таблицами рядом с Users и PostHelpfuls , чем PostHelpfuls связаны с таблицами рядом с Пользователи и Посты .

...