【问题标题】:SQL Server: Self-reference FK, trigger instead of ON DELETE CASCADESQL Server:自引用 FK,触发器而不是 ON DELETE CASCADE
【发布时间】:2009-11-23 15:09:15
【问题描述】:

我需要在名为 CATEGORY 的表上执行 ON DELETE CASCADE,该表具有以下列 CAT_ID(大整数) 名称(VARCHAR) PARENT_CAT_ID (BIGINT)

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

当我手动删除包含子类别的类别时,出现以下异常:

知道我的触发器有什么问题吗?

更新: 抱歉编辑,但我有另一列 CATEGORY.CAT_SCH_ID,它是另一个表 CAT_SCH.ID 的 FK。这个 FK 也有一个 CASCADE DELETE,这意味着一旦我删除了一个 CAT_SCH,它的 CATEGOries 也必须被删除。所以,当我定义触发器时,我得到了这个错误:

无法在表 'CATEGORY' 上创建 INSTEAD OF DELETE 或 INSTEAD OF UPDATE TRIGGER 'TRG_DEL_CATEGORY_WITH_CHILDREN'。这是因为表有一个 FOREIGN KEY 级联 DELETE 或 UPDATE。

有什么想法吗?

【问题讨论】:

    标签: sql sql-server foreign-keys triggers cascade


    【解决方案1】:

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

    算法是这样的:

    • 将删除的 PK 插入临时表中

    • 查找临时表中记录的详细记录

    • 循环直到找不到更多记录

    通过加入临时表删除表中的记录。

    我描述了递归删除in my blog

    更新

    我猜你只需要从类别中的递归外键中删除那个 ON DELETE CASCADE 标志。来自 CAT_SCH 的外键上的 CASCADE 标志应该无关紧要。

    【讨论】:

    • 感谢您的回复!看起来正是我需要的,但是有一个小问题,你能看一下更新吗?谢谢。
    • 抱歉,无法在具有 on delete 级联的表上定义 INSTEAD OF DELETE...
    猜你喜欢
    • 2011-09-21
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多