sql - 如何在 SQL Server 2005 中模拟 BEFORE DELETE 触发器

标签 sql sql-server sql-server-2005 tsql triggers

假设我有三个表:[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] 值删除之前的 [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 中没有这样的东西。由于级联 FK,我无法使用 INSTEAD OF 触发器。

我的印象是,如果我使用 FOR DELETE 触发器,当我将 [deleted] 连接到 [ONE_TWO] 以查找 [ONE_ID] 值列表时,FK 级联将已经删除了关联的 [ONE_TWO] 记录,因此我永远找不到任何 [ONE_ID] 值。这是真的?如果是这样,我怎样才能实现我的目标?

我认为我需要将连接 [TWO] 的 FK 更改为 [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

一些示例值

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

关于sql - 如何在 SQL Server 2005 中模拟 BEFORE DELETE 触发器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4672731/

相关文章:

mysql - SQL语句命名3个id标签

c# - 来自 SqlDataReader 的转换问题

java - 在JPA中的persistence.xml中建立ms sql连接

c# - 将连接字符串存储在数据库中并在应用程序启动时检索它

sql-server - 如何从更多列中选择但按 1 列分组?

MySQL - 使用占位符作为不返回任何行的子查询的值

mysql - SQL 不同的最新帖子

sql - 如何在不使用 JOIN 的情况下将 2 个表中的列合并为 1 个表

sql-server-2005 - 如何使用T-SQL正确连接列?

sql - 将周日期部分编号转换为周内的日期(...的一周)