Let me start out trying to explain… My MSSQL2008 R2 database has two tables, one called SalesHeader the other SalesDetails . If I delete a header record it cascades and deletes all details related to that header. I also have an on delete trigger on the SalesDetails table that renumbers the DetailNumber field for the remaining details.
The Cascade on delete worked before I put in the Trigger on the Details table. The trigger works now but I get an error when trying to delete a header record. I can manually disable the delete trigger on details table and the header delete works as expected.
To fix this I am not quite sure whether a new on delete trigger on the header table that would disable the trigger on the details table would work or if there is a way to detect the Cascade on Delete in the Details trigger so the trigger logic could be bypassed. I have read here on SO that INSTEAD OF DELETE Triggers are not allowed with Cascade on Delete.
Any suggestions would be greatly appreciated and code snippets even more so.
Cheers,
SQL Trigger:
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
I found my fix.
SET @Count = (SELECT
COUNT(*)
FROM DELETED)
-- We want to break for multiple rows (ON DELETE CASCADE)
IF (@Count > 1) RETURN
I only delete single rows from the ChildTable at a time. I also want to keep the cascade on delete - as my ChildTable has Children of its own.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.