触发器
当发生某一事件时,如果满足给定条件,则执行相应的动作
创建触发器
1 | CREATE TRIGGER [schema_name.]trigger_name |
说明
schema_name
是新触发器所属模式的名称。模式名称是可选的。trigger_name
是要创建触发器的用户定义名称。table_name
是触发器作用的表。- 事件列在
AFTER
子句中。事件可以是INSERT
,UPDATE
或DELETE
。单个触发器可以响应针对该表的一个或多个动作而触发。 NOT FOR REPLICATION
选项指示SQL Server在复制过程中进行数据修改时不触发触发器。sql_statements
是一个或多个Transact-SQL,用于在事件发生后执行操作。
触发器的虚拟表
SQL Server提供了两个专门用于名为INSERTED
和DELETED
表的触发器的虚拟表。
SQL Server使用这些表来捕获事件发生之前
和之后
修改行的数据。
下表显示了INSERTED
和DELETED
表每个事件之前和之后的内容:
DML事件 | INSERTED表持有 | DELETED表持有 |
---|---|---|
INSERT | 要插入的行 | 空 |
UPDATE | 更新修改的新行 | 更新修改的现有行 |
DELETE | 空 | 要删除的行 |
案例
创建一张新表,用于存放Student表的插入与删除操作的日志信息
1 | CREATE TABLE Student_logs( |
创建触发器
1 | CREATE TRIGGER trg_student_logs |
INSTEAD OF触发器
INSTEAD OF
触发器是一种触发器,用于跳过对表或视图的INSERT,DELETE或UPDATE语句,并执行触发器中定义的其他语句。根本不会发生实际的插入,删除或更新操作。
换句话说,INSTEAD OF
触发器会跳过DML
语句并执行其他语句。
1 | CREATE TRIGGER [schema_name.] trigger_name |
说明
- 首先,在
CREATE TRIGGER
子句中指定触发器的名称以及触发器所属的模式的名称。 - 其次,指定触发器关联的表或视图的名称。
- 第三,指定触发器将在
INSTEAD OF
子句中触发的事件,如INSERT
,DELETE
或UPDATE
。 可以调用触发器以响应一个或多个事件。 - 第四,将触发器主体放在
AS
关键字之后。 触发器的主体可能包含一个或多个Transact-SQL语句。
实例
使用INSTEAD OF
触发器的典型示例是覆盖视图上的插入,更新或删除操作。
假设,应用程序需要将新品牌插入到production.brands
表中。 但是,在插入到production.brands
表之前,新品牌应存储在另一个名为production.brand_approvals
的表中以供批准。
为此,需要为应用程序创建名为production.vw_brands
的视图以插入新品牌。 如果将品牌插入到视图中,则会触发INSTEAD OF
触发器以将品牌插入到production.brand_approvals
表中。
DDL触发器
SQL Server DDL触发器响应服务器或数据库事件而不是表数据修改。 这些事件由Transact-SQL语句创建,通常以以下关键字之一:CREATE
,ALTER
,DROP
,GRANT
,DENY
,REVOKE
或UPDATE STATISTICS
开头。
1 | CREATE TRIGGER trigger_name |
说明
trigger_name
- 在CREATE TRIGGER
关键字后指定用户定义的触发器名称。 请注意,不必为DDL触发器指定模式,因为它与实际的数据库表或视图无关。DATABASE | ALL SERVER
- 如果触发器响应数据库范围的事件,则使用DATABASE
;如果触发器响应服务器范围的事件,则使用ALL SERVER
。ddl_trigger_option
- 用于指定ENCRYPTION
和/或EXECUTE AS
子句。ENCRYPTION
加密触发器的定义。EXECUTE AS
定义执行触发器的安全上下文。event_type | event_group
- 表示导致触发器触发的DDL事件,例如,CREATE_TABLE
,ALTER_TABLE
等。event_group
是一组event_type
事件,例如DDL_TABLE_EVENTS
。- 触发器可以订阅一个或多个事件或事件组。
作用
DDL触发器在以下情况下很有用:
- 记录数据库模式中的更改。
- 防止对数据库模式进行某些特定更改。
- 响应数据库模式的更改。
实例
禁用触发器
有时,为了进行故障排除或数据恢复,可能需要暂时禁用触发器。
1 | DISABLE TRIGGER [schema_name.][trigger_name] |
说明
- 首先,指定触发器所属的模式名称以及
DISABLE TRIGGER
关键字后要禁用的触发器的名称。 - 其次,如果触发器是DML触发器,请指定触发器绑定的表名或视图。 如果触发器是DDL数据库范围的触发器,则使用
DATABASE
;如果触发器是DDL服务器范围的触发器,则使用ALL SERVER
。
实例
创建一个简单的显示信息的触发器,然后禁止它。
1 | CREATE TRIGGER prt_stu |
禁止该触发器
1 | DISABLE TRIGGER prt_stu |
成功禁用了!
启用触发器
1 | ENABLE TRIGGER [schema_name.][trigger_name] |
实例
1 | ENABLE TRIGGER prt_stu |
成功启用!
查看触发器定义
通过从系统视图查询获取触发器定义
1 | SELECT |
使用OBJECT_DEFINITION函数获取触发器定义
1 | SELECT |
结果不全,因为我设置了“查询选项”每列最多256字符。
使用sp_helptext存储过程获取触发器定义
1 | EXEC sp_helptext '[trigger_name]' ; |
使用SSMS获取触发器定义
在图形化界面中找到对应的触发器,右键点击修改。
列出所有触发器
1 | SELECT |
删除触发器
DROP TRIGGER
语句用于从数据库中删除一个或多个触发器
1 | DROP TRIGGER [ IF EXISTS ] [schema_name.]trigger_name [ ,...n ]; |
说明
IF EXISTS
仅在已经存在的情况下有条件地移除触发器。schema_name
是DML触发器所属的模式名称。trigger_name
是将要删除的触发器的名称。
如果要一次删除多个触发器,则需要用逗号分隔触发器。
要删除一个或多个DDL触发器
1 | DROP TRIGGER [ IF EXISTS ] trigger_name [ ,...n ] |
说明
DATABASE
表示DDL触发器的范围适用于当前数据库。ALL SERVER
指示DDL触发器的范围适用于当前服务器。
要删除LOGON
事件触发器
1 | DROP TRIGGER [ IF EXISTS ] trigger_name [ ,...n ] |
请注意,当删除表时,与表关联的所有触发器也会自动删除。