SQL Server: самоссылка FK, триггер вместо ON DELETE CASCADE

Мне нужно выполнить ON DELETE CASCADE в моей таблице с именем CATEGORY, которая имеет следующие столбцы CAT_ID (BIGINT) NAME (VARCHAR) PARENT_CAT_ID (BIGINT)

PARENT_CAT_ID — это FK на CAT_ID. Очевидно, прекрасный SQL Server не позволяет мне использовать ON DELETE CASCADE, заявляя о циклическом или множественном пути к удалению.

Решение, которое я часто вижу, — это триггеры. Я сделал следующий триггер:

USE [ma]
GO
/****** Object:  Trigger [dbo].[TRG_DELETE_CHILD_CATEGORIES]    Script Date: 11/23/2009 16:47:59 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[TRG_DELETE_CHILD_CATEGORIES] ON [dbo].[CATEGORY] FOR DELETE AS
SET NOCOUNT ON
/* * CASCADE DELETES TO '[Tbl B]' */
DELETE CATEGORY FROM deleted, CATEGORY WHERE deleted.CAT_ID = CATEGORY.PARENT_CAT_ID

Когда я вручную удаляю категорию с дочерними категориями, я получаю следующее исключение:

исключение

Есть идеи, что не так с моим триггером?

ОБНОВЛЕНИЕ: извините за редактирование, но у меня есть еще один столбец CATEGORY.CAT_SCH_ID, который является FK другой таблицы CAT_SCH.ID. Этот FK также имеет CASCADE DELETE, что означает, что как только я удаляю CAT_SCH, его CATEGORies также должны быть удалены. Итак, я получаю эту ошибку, когда определяю триггер:

Невозможно создать INSTEAD OF DELETE или INSTEAD OF UPDATE TRIGGER 'TRG_DEL_CATEGORY_WITH_CHILDREN' для таблицы 'CATEGORY'. Это связано с тем, что таблица имеет FOREIGN KEY с каскадным DELETE или UPDATE.

Любые идеи?


person Markos Fragkakis    schedule 23.11.2009    source источник


Ответы (1)


Триггер FOR DELETE срабатывает после выполнения исходного DELETE. Для рекурсивного удаления нужно написать триггер INSTEAD OF DELETE.

Алгоритм такой:

  • Вставьте ПК из удаленных во временную таблицу

  • Найти подробные записи записей во временной таблице

  • Цикл, пока не будет найдено больше записей

УДАЛИТЬ записи в таблице, присоединившись к временной таблице.

Я описал рекурсивное удаление в своем блоге.

Обновить

Я думаю, вам просто нужно удалить этот флаг ON DELETE CASCADE из вашего рекурсивного внешнего ключа в категориях. Флаг CASCADE на внешнем ключе от CAT_SCH не должен иметь значения.

person devio    schedule 23.11.2009
comment
Спасибо за ответ! Вроде то что нужно, но есть маленькая проблемка, не могли бы вы глянуть обновление? Спасибо. - person Markos Fragkakis; 23.11.2009
comment
Извините, но нельзя определить INSTEAD OF DELETE для таблицы с каскадом при удалении... - person Bellash; 18.09.2014