Mar*_*man 4 sql t-sql sql-server triggers sql-server-2005
假设我有三个表,[ONE],[ONE_TWO]和[TWO].[ONE_TWO]是一个多对多连接表,只有[ONE_ID和[TWO_ID]列.设置了外键以将[ONE]链接到[ONE_TWO]和[TWO]到[ONE_TWO].FK使用ON DELETE CASCADE选项,以便在删除[ONE]或[TWO]记录时,相关的[ONE_TWO]记录也将自动删除.
我希望在[TWO]表上有一个触发器,这样当删除[TWO]记录时,它会执行一个存储过程,该过程以[ONE_ID]作为参数,传递链接到[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)
Run Code Online (Sandbox Code Playgroud)
显然,我需要一个BEFORE DELETE触发器,但在SQL Server 2005中没有这样的东西.由于级联FK,我无法使用INSTEAD OF触发器.
我得到的印象是,如果我使用FOR DELETE触发器,当我将[deleted]连接到[ONE_TWO]以查找[ONE_ID]值的列表时,FK级联将已经删除了相关的[ONE_TWO]记录,所以我永远不会找到任何[ONE_ID]值.这是真的?如果是这样,我怎样才能实现我的目标?
我想我需要将FK加入[TWO]改为[ONE_TWO]以不使用级联并在我手动删除[TWO]记录之前在触发器中手动从[ONE_TWO]进行删除.但如果有更简单的方法,我宁愿不经历所有这些.
您可以使用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
Run Code Online (Sandbox Code Playgroud)
一些样本值
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
Run Code Online (Sandbox Code Playgroud)
现在测试一下
delete two where two_id=13
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6905 次 |
| 最近记录: |