2011-01-12 35 views
4

假設我有三個表格[ONE],[ONE_TWO]和[TWO]。 [ONE_TWO]是隻有[ONE_ID和[TWO_ID]列的多對多連接表。有外鍵設置爲將[ONE]鏈接到[ONE_TWO],[TWO]鏈接到[ONE_TWO]。 FK使用ON DELETE CASCADE選項,這樣如果刪除[ONE]或[TWO]記錄,關聯的[ONE_TWO]記錄也會自動刪除。如何模擬SQL Server 2005中的BEFORE DELETE觸發器

我希望在[TWO]表上有一個觸發器,這樣當一個[TWO]記錄被刪除時,它會執行一個存儲過程,它將一個[ONE_ID]作爲參數,傳遞已經存在的[ONE_ID]掛[TWO_ID]之前刪除發生:

DECLARE @Statement NVARCHAR(max) 
SET @Statement = '' 
SELECT @Statement = @Statement + N'EXEC [MyProc] ''' + CAST([one_two].[one_id] AS VARCHAR(36)) + '''; ' 
FROM deleted 
JOIN [one_two] ON deleted.[two_id] = [one_two].[two_id] 

EXEC (@Statement) 

很顯然,我需要一個BEFORE DELETE觸發器,但在SQL Server中沒有這樣的事情我2005年不能使用,因爲的INSTEAD OF觸發器級聯FK。

我得到的印象是,如果我使用FOR DELETE觸發器,當我加入[刪除]到[ONE_TWO]以查找[ONE_ID]值列表時,FK級聯將已經刪除相關的[ONE_TWO]記錄所以我永遠不會找到任何[ONE_ID]值。這是真的?如果是這樣,我該如何實現我的目標?

我想我需要改變FK加入[TWO]到[ONE_TWO]不使用級聯,並在手動刪除[TWO]之前手動刪除[ONE_TWO] ] 記錄。但是,如果有一種更簡單的方法,我寧願不這樣做。

回答

8

您可以使用INSTEAD OF觸發器。它在實際刪除之前觸發(替換),因此[one_two]中的鏈接記錄必須仍然存在。

create table [one] (one_id int not null primary key) 
create table [two] (two_id int not null primary key) 
create table [one_two] (one_id int, two_id int references two(two_id) on delete cascade) 
GO 
CREATE trigger t_del_two 
on two 
instead of delete 
as 
begin 
SET NOCOUNT ON 
DECLARE @Statement NVARCHAR(max) 
SET @Statement = '' 
SELECT @Statement = @Statement + N'EXEC [MyProc] ''' + CAST([one_two].[one_id] AS VARCHAR(36)) + '''; ' 
FROM deleted 
JOIN [one_two] ON deleted.[two_id] = [one_two].[two_id] 

PRINT (@Statement) 
--EXEC (@Statement) 

-- carry out the actual delete 
DELETE TWO WHERE two_id in (SELECT two_id from deleted) 
end 
GO 

一些樣本值

insert into one select 1 
insert into one select 2 
insert into one select 3 
insert into two select 11 
insert into two select 12 
insert into two select 13 
insert into one_two select 1,11 
insert into one_two select 1,13 
insert into one_two select 2,13 

現在測試一下

delete two where two_id=13 
+0

這個工作,但我的情況和你所提供的測試之間的區別是,我的表有外鍵約束這一切都有所不同。 create table [one_two](one_id int,two_id int); 。 ALTER TABLE [DBO] [one_two] ADD CONSTRAINT [FK_one_two__one_oneid] 外鍵([one_id]) 參考文獻[DBO] [酮]([one_id]) ON DELETE CASCADE。 ALTER TABLE [DBO] [one_two] ADD CONSTRAINT [FK_one_two__two_twoid] 外鍵([two_id]) 參考文獻[DBO] [2]([two_id]) ON DELETE CASCADE。; 此更改會導致測試失敗。 – 2011-01-19 23:18:53