如果触发Cascade On Delete,如何禁用触发器

时间:2014-09-11 16:41:45

标签: sql sql-server triggers cascade

让我开始尝试解释...我的MSSQL2008 R2数据库有两个表,一个名为 SalesHeader ,另一个名为 SalesDetails 。如果我删除标题记录,它会级联并删除与该标题相关的所有详细信息。我还在 SalesDetails 表上有一个on delete触发器,它为 DetailNumber 字段重新编号以获取其余的详细信息。

在我在Details表上输入Trigger之前,Cascade on delete工作正常。触发器现在可以正常工作,但在尝试删除标题记录时出现错误。我可以手动禁用详细信息表上的删除触发器,并且标头删除按预期工作。

为了解决这个问题,我不太确定是否会在标头表上删除触发器上的新触发器将禁用详细信息表上的触发器,或者是否有一种方法可以在详细信息触发器中检测“删除时级联”,以便可以绕过触发逻辑。我已经在这里读到了 INSTEAD OF DELETE 删除时Cascade不允许使用触发器。

任何建议都会受到高度赞赏,而且代码片段更是如此。

干杯,

SQL触发器:

    USE [MyDatabase]
    GO

    /****** Object:  Trigger [dbo].[OnDeleteTrigger]    Script Date: 9/11/2014 11:51:40 AM ******/
    SET ANSI_NULLS ON
    GO

    SET QUOTED_IDENTIFIER ON
    GO


    -- =============================================
    -- Author:      Randy Gordey
    -- Create date: 08/28/2014
    -- Description: Renumbers the remaining details
    --              when rows are deleted.
    -- =============================================
    CREATE TRIGGER [dbo].[OnDeleteTrigger] 
       ON  [dbo].[SalesDetail] 
       AFTER DELETE
    AS 
    BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here
    PRINT 'Delete Trigger Fired'
    DECLARE @ID int
    DECLARE @RowNum int
    DECLARE @TransactionNumber int

    -- Gets the TransactionNumber from the deleted row
    SET @TransactionNumber = (SELECT
       intTransactionNumber
    FROM DELETED)

    DECLARE myCursor CURSOR

    /** Gets a collection of the detail lines for this Transaction **/
    LOCAL SCROLL STATIC FOR SELECT
       intDetailNumber,
       ROW_NUMBER() OVER (ORDER BY intDetailNumber) AS 'RowNum'
    FROM SalesDetail
    WHERE intTransactionNumber = @TransactionNumber;

    OPEN myCursor;

    -- Grabs the first row
    FETCH NEXT FROM myCursor INTO @ID, @RowNum;

    -- Begin Loop
    WHILE @@FETCH_STATUS = 0 BEGIN

    /** Updates Database: Setting new Detail Number for each row. **/
    UPDATE SalesDetail
    -- intDetailNumber is part of the PrimaryKey but it is not
    -- set as an identity, so we can still change it.
       SET intDetailNumber = @RowNum
       WHERE intDetailNumber = @ID
       AND intTransactionNumber = @TransactionNumber;

    -- Grabs the next row
    FETCH NEXT FROM myCursor INTO @ID, @RowNum;

    END;
    CLOSE myCursor;
    DEALLOCATE myCursor;

    END
    GO

1 个答案:

答案 0 :(得分:0)

我找到了解决办法。

    SET @Count = (SELECT
    COUNT(*)
    FROM DELETED)

    -- We want to break for multiple rows (ON DELETE CASCADE)
    IF (@Count > 1) RETURN

我一次只删除ChildTable中的单行。我还想保留删除级联 - 因为我的ChildTable有自己的子项。