SQL Server 触发器切换插入、删除、更新

Posted

技术标签:

【中文标题】SQL Server 触发器切换插入、删除、更新【英文标题】:SQL Server Trigger switching Insert,Delete,Update 【发布时间】:2010-12-17 15:02:34 【问题描述】:

您好可以在触发器主体上的 DML 命令/操作(插入、删除、更新)之间切换吗?我尝试 sn-p 一些 T-SQL 以更好地理解我:

CREATE TRIGGER DML_ON_TABLEA
   ON  TABLEA
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    CASE 
    WHEN (INSERT) THEN
        -- INSERT ON AUX TABLEB 
    WHEN (DELETE) THEN
        -- DELETE ON AUX TABLEB 
    ELSE --OR WHEN (UPDATE) THEN
        -- UPDATE ON AUX TABLEB 
    END
END
GO

谢谢,

【问题讨论】:

【参考方案1】:

我将向您展示一种在 SQL Server 2000 或 2005 中检查这一点的简单方法(您忘记提及您使用的是哪个版本),但总的来说,我同意 Remus 的观点,即您应该将它们分解为单独的触发器:

DECLARE @i INT, @d INT;
SELECT @i = COUNT(*) FROM inserted;
SELECT @d = COUNT(*) FROM deleted;
IF @i + @d > 0
BEGIN
    IF @i > 0 AND @d = 0
    BEGIN
        -- logic for insert
    END

    IF @i > 0 AND @d > 0
    BEGIN
        -- logic for update
    END

    IF @i = 0 AND @d > 0
    BEGIN
        -- logic for delete
    END
END

请注意,由于MERGE 在 SQL Server 2008 中引入的复杂性,这可能无法完全向前兼容。有关详细信息,请参阅此连接项:

MERGE can cause a trigger to fire multiple times

因此,如果您计划将来使用 SQL Server 2008 和MERGE,那么这更有理由将触发器拆分为每种 DML 操作类型的触发器。

(如果您想有更多理由避免使用MERGE、read this 和this。)

【讨论】:

+1 表示“拆分触发器的更多理由”。这确实节省了很多时间,而且只是“有道理”——当单独的触发器也能完成工作时,为什么还要费心去弄清楚需要做什么。谢谢@Aaron。 这是 Aaron 提到的 Microsoft Connect(现已停用)项目的链接:connect.microsoft.com:80/SQLServer/feedback/details/321930/… @MarkVarnas 我更新了网址。你现在必须通过 WayBack 机器。【参考方案2】:

您可以通过使用联合连接将一个触发器用于所有命令/操作;

CREATE TRIGGER DML_ON_TABLEA
 ON  TABLEA
AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
   --logic for insert
    insert into Backup_table (columns_name) select columns_name from inserted i
    --logic for delete
   UNION ALL
    insert into Backup_table (columns_name) select columns_name from deleted d
END
GO

--注意更新命令,如插入命令,但删除另一个命令

【讨论】:

【参考方案3】:

我认为执行此操作的一般方法是为每个操作创建一个触发器,如下所示:

CREATE TRIGGER INSERT_ON_TABLEA   
ON  TABLEA   
AFTER INSERT 
AS 
BEGIN    
SET NOCOUNT ON;    
-- INSERT ON AUX TABLEB
END
GO

CREATE TRIGGER DELETE_ON_TABLEA   
ON  TABLEA   
AFTER DELETE
AS 
BEGIN    
SET NOCOUNT ON;    
-- DELETE ON AUX TABLEB
END
GO

【讨论】:

【参考方案4】:

您可以使用inserted and deleted tables 查看对表格进行了哪些更改。

对于 UPDATE,deleted 表包含行的旧版本,inserted 包含新版本。

DELETE 和 INSERT 使用它们自己的表,正如您所期望的那样。

【讨论】:

【参考方案5】:

您可以拥有三个独立的触发器,一个用于 INSERT,一个用于 UPDATE,一个用于 DELETE。由于每个触发器都不一样,所以不需要切换逻辑。

【讨论】:

以上是关于SQL Server 触发器切换插入、删除、更新的主要内容,如果未能解决你的问题,请参考以下文章

Sql Server 2005 - 插入更新触发器 - 获取更新,插入行

SQL Server - 使用表触发器记录表插入,更新,删除行数

SQL Server - 在模式中触发AFTER INSERT表

创建TRIGGER以插入,更新和删除使用视图 - SQL SERVER

SQL Server在复制时触发

在 SQL Server 2008 R2 中为每个表创建创建触发器