2009-11-23 100 views
4

我需要执行一个ON DELETE CASCADE我的表名为类,它具有以下columls CAT_ID(BIGINT) NAME(VARCHAR) PARENT_CAT_ID(BIGINT )SQL服务器:自引用FK,触发代替ON DELETE CASCADE

PARENT_CAT_ID是CAT_ID上的FK。显然,可爱的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 

当我手动删除与子类别的类别,我得到以下异常:

exception

任何想法有什么不对我的触发器?

UPDATE: 很抱歉的编辑,但我有另一列CATEGORY.CAT_SCH_ID,这是另一个表CAT_SCH.ID的FK。这个FK也有一个CASCADE DELETE,这意味着一旦我删除一个CAT_SCH,它的CATEGORIES也必须被删除。因此,当我定义触发器时,出现此错误:

无法在表'CATEGORY'上创建INSTEAD DELETE或INSTEAD UPDATE TRIGGER'TRG_DEL_CATEGORY_WITH_CHILDREN'。这是因为该表具有带级联DELETE或UPDATE的FOREIGN KEY。

任何想法?

回答

12

原始DELETE已执行后,将删除触发器。要递归删除,您需要编写一个INSTEAD OF DELETE触发器。

的算法是这样的:

  • 插入的PK从删除到一个临时表

  • 在临时表中找到的记录详细记录

  • 循环播放,直到没有更多的记录找到

DELETE记录在t他通过加入临时表来表格。

我描述了递归删除in my blog

更新

我猜你只需要丢弃来自于分类的递归外键DELETE CASCADE标志。来自CAT_SCH的外键上的CASCADE标志应该没有关系。

+0

感谢您的回应!这看起来正是我需要的,但是有一个小问题,你可以看看更新吗?谢谢。 – 2009-11-23 16:18:02

+0

对不起,但不能在删除级联上的表上定义'INSTEAD OF DELETE'... – Bellash 2014-09-18 11:51:15