可以通过“而不是触发器”完全替换“触发后”吗?

时间:2015-02-27 11:51:18

标签: sql sql-server triggers

我知道基本的触发器概念,并在学习它时使用它。我没有太多实际经验,因为我很少使用它。现在我的问题是,所有触发后是否可以完全被而不是触发器替换?

对我而言而不是触发器是一种“触发前”,它会在动作发生之前触发。所以我们可以做一些有用的事情,或者回滚事务。由于我们可以做任何事情,我们可以INSERT, UPDATE, DELETE。对我来说,似乎我可以使用而不是触发器来完全替换触发后的 。这是真的吗?

以下是针对SQL Server的示例。这两个触发器的目的是防止删除。看来它们都有效。

USE test;
GO
IF OBJECT_ID(N'dbo.a', N'U') IS NOT NULL
    DROP TABLE dbo.a;
GO

CREATE TABLE dbo.a (id INT, c1 INT);
GO

INSERT  INTO a
VALUES  (1, 1);
GO

-- instead of trigger
IF OBJECT_ID('dbo.t1', 'TR') IS NOT NULL
    DROP TRIGGER dbo.t1;
GO
CREATE TRIGGER dbo.t1 ON dbo.a
    INSTEAD OF DELETE
AS
BEGIN
    ROLLBACK;
    PRINT 't1: Not allowed to delete data  from dbo.a';
END
GO


-- delete a row from the table to test the trigger
DELETE  FROM a
WHERE   id = 1;
-- and it works!

-- drop the first trigger
IF OBJECT_ID('dbo.t1', 'TR') IS NOT NULL
    DROP TRIGGER dbo.t1;
GO

-- create an after trigger
IF OBJECT_ID('dbo.t2', 'TR') IS NOT NULL
    DROP TRIGGER dbo.t2;
GO
CREATE TRIGGER dbo.t2 ON dbo.a
    AFTER DELETE
AS
BEGIN
    ROLLBACK;
    PRINT 't2: Not allowed to delete data  from dbo.a';
END
GO


-- delete a row from the table to test the trigger
DELETE  FROM a
WHERE   id = 1;
-- and it works!


-- drop the second trigger
IF OBJECT_ID('dbo.t2', 'TR') IS NOT NULL
    DROP TRIGGER dbo.t2;
GO

1 个答案:

答案 0 :(得分:1)

是的,除了你必须记住在后触发器中已经发生了动作之外,它们可以被认为是等效的 - 通常通过回滚来取消它。

在一个触发器而不是触发器中,没有发生动作,而是由你(在触发器中)来执行动作。后触发通常作为审计步骤完成。而不是通常做以防止发生的事情。

在任何一种情况下都会填充已删除和插入的表。

您可以单步执行以下代码来验证我刚刚说过的内容:

drop table dbo.t1

创建表dbo.t1(i1 int)

插入dbo.t1值(1),(5),(6)

从dbo.t1

中选择*

在dbo.t1上创建触发器dbo.t2trig
删除AS后

开始

select * from deleted

print 'in after trigger dbo.t1trig'

从dbo.t1删除i1< 6

从dbo.t1

中选择*

插入dbo.t1值(1),(5)

从dbo.t1

中选择*

drop trigger dbo.t2trig

在dbo.t1上创建触发器dbo.t2trig
而不是删除AS

开始

select * from deleted

print 'in trigger instead of dbo.t1trig'

插入dbo.t1值(1),(5)

从dbo.t1删除i1< 6

从dbo.t1

中选择*