"after trigger"可以完全被"instead of trigger"代替吗?
Can "after trigger" be replaced completely by "instead of trigger"?
我知道基本的触发器概念,并且在学习时玩过它。我没有太多实践经验,因为我很少使用它。现在我的问题是,所有after trigger都可以完全替换为instead trigger吗?
对我来说 而不是触发器 是一种 "before trigger",它会在操作发生之前触发。所以我们可以做一些有用的事情,或者回滚事务。既然我们无所不能,我们就可以INSERT, UPDATE, DELETE
。对我来说,我似乎可以使用 而不是 trigger 来完全替换 after trigger。是真的吗?
下面是针对 SQL 服务器的示例。这两个触发器的目的是防止删除。似乎他们两个都有效。
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
是的,它们可以等效,除非您必须记住在后触发器中已经发生了操作 - 通常由您通过回滚来撤消它。
在代替触发器中,操作尚未发生,由您(在触发器中)执行操作。后触发通常作为审计步骤完成。通常使用 instead of 来防止某些事情发生。
已删除和已插入的 table 在任何一种情况下都会被填充。
你可以通过下面的代码来验证我刚才说的:
删除 table dbo.t1
创建table dbo.t1 (i1 int)
插入 dbo.t1 值 (1),(5), (6)
select * 来自 dbo.t1
;
去
在 dbo.t1 上创建触发器 dbo.t2trig
删除后 AS
开始
select * from deleted
print 'in after trigger dbo.t1trig'
结束
从 dbo.t1 中删除 i1 < 6
select * 来自 dbo.t1
插入 dbo.t1 值 (1),(5)
select * 来自 dbo.t1
;
去
删除触发器 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
select * 来自 dbo.t1
我知道基本的触发器概念,并且在学习时玩过它。我没有太多实践经验,因为我很少使用它。现在我的问题是,所有after trigger都可以完全替换为instead trigger吗?
对我来说 而不是触发器 是一种 "before trigger",它会在操作发生之前触发。所以我们可以做一些有用的事情,或者回滚事务。既然我们无所不能,我们就可以INSERT, UPDATE, DELETE
。对我来说,我似乎可以使用 而不是 trigger 来完全替换 after trigger。是真的吗?
下面是针对 SQL 服务器的示例。这两个触发器的目的是防止删除。似乎他们两个都有效。
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
是的,它们可以等效,除非您必须记住在后触发器中已经发生了操作 - 通常由您通过回滚来撤消它。
在代替触发器中,操作尚未发生,由您(在触发器中)执行操作。后触发通常作为审计步骤完成。通常使用 instead of 来防止某些事情发生。
已删除和已插入的 table 在任何一种情况下都会被填充。
你可以通过下面的代码来验证我刚才说的:
删除 table dbo.t1
创建table dbo.t1 (i1 int)
插入 dbo.t1 值 (1),(5), (6)
select * 来自 dbo.t1
; 去
在 dbo.t1 上创建触发器 dbo.t2trig
删除后 AS
开始
select * from deleted
print 'in after trigger dbo.t1trig'
结束
从 dbo.t1 中删除 i1 < 6
select * 来自 dbo.t1
插入 dbo.t1 值 (1),(5)
select * 来自 dbo.t1
; 去
删除触发器 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
select * 来自 dbo.t1