Вместо триггеров и каскадных путей
Допустим, у меня есть 3 таблицы в иерархии:
TableA -> TableB -> TableC
TableC
имеет отношение внешнего ключа с TableB
и TableB
имеет отношение внешнего ключа с TableA
.
если я удалю запись в TableA
, он должен каскадировать удаление вниз по иерархии. Используя ON DELETE CASCADE
будет работать нормально.
однако, скажем, мне нужно поставить INSTEAD OF
триггер TableC
. Насколько я понимаю, это INSTEAD OF
триггер не может быть поставлен на стол, который имеет каскад удаления, идущий к нему. Взято из MSDN:
для вместо триггеров параметр DELETE не разрешен для таблиц, имеющих ссылочную связь, указывающую каскадное действие при удалении.
если я должен снять каскад удалитьTableB->TableC
, мне нужно использовать INSTEAD OF
триггеров для обеспечения ссылочной целостности, а то у меня такая же проблема с TableB->TableA
. Это простой пример, но представьте, что каскадный путь очень больше. Кажется, что это может легко снежный ком на протяжении долгого каскадного пути.
Итак, каковы наилучшие методы работы с этим сценарием?
2 ответов
предполагая, что вы должны использовать вместо триггеров, и после того, как триггеры не являются опцией, лучшим подходом является a) плотно контролировать схему, чтобы вы могли b) сценарий вместо триггеров регулярно реализовывать каскадное удаление и любые другие необходимые Вам операции.
создайте ограничения FK, как и раньше, но без какого-либо каскадного поведения. В имени FK используйте некоторое соглашение, чтобы указать, какое каскадное поведение и пользовательское поведение должно происходить, например:
- FK_UC_DC_Table1_Table2 -- обновить каскад, удалить каскад
- FK_UC_DN_Table1_Table3 -- обновить каскад, удалить набор null
используйте все, что имеет смысл, но создайте FKs, они являются полезными метаданными для генерации кода, и вы можете использовать имена FK для записи директив для генератора кода.
затем я бы сделал еще один шаг и изолировал эти таблицы в их собственной схеме. Они не будут вести себя так же, как другие таблицы, и они будут более глючными сначала, когда вы тестируете и настраиваете генерацию кода. Лучше всего держать все это в карантине и легко идентифицировать по общему контейнеру.
выделенная схема также сообщит любому, кто изменяет данные, которые применяются различные правила и поведение.
стандартная передовая практика заключается в определении вместо триггеров на вид, а не таблицы.
Если вам нужно использовать триггер для обновления/удаления FK, лучше всего использовать его после, так как он всегда будет выполняться.
Если вы хотите отменить каскадные действия, но сохранить FKs, просто установите для действия FK значение NO ACTION.