一、什么是触发器(trigger)?
触发器(trigger)是一种特殊的存储过程,它不会被人为调用,而是在对表执行特定操作时自动触发执行。
常见触发条件包括:
insert(插入数据)update(更新数据)delete(删除数据)
可以理解为:
当表发生变化时,数据库自动执行的一段“监听程序”。
触发器的典型用途
数据审计(记录谁改了什么数据)
数据校验(防止非法操作)
自动维护关联数据
业务规则约束(如库存不能为负)
二、触发器的分类
sql server 中主要有两类触发器:
1. dml 触发器(针对表)
作用对象:insert / update / delete
分为两种:
(1)after 触发器(之后触发)
在操作完成后执行。
create trigger trg_afterinsert
on student
after insert
as
begin
print '插入数据成功'
end(2)instead of 触发器(替代执行)
替代原本的操作执行,常用于视图或复杂逻辑控制。
create trigger trg_insteaddelete
on student
instead of delete
as
begin
print '禁止删除学生记录'
end2. ddl 触发器(针对数据库级操作)
用于监听:
create table
drop table
alter table
create login 等
create trigger trg_ddl
on database
for drop_table
as
begin
print '禁止删除表结构'
end三、inserted 与 deleted 表(核心概念)
在 dml 触发器中,sql server 提供了两个虚拟表:
| 操作 | inserted 表 | deleted 表 |
|---|---|---|
| insert | 新数据 | 空 |
| delete | 空 | 原数据 |
| update | 新数据 | 旧数据 |
示例:记录学生表修改日志
create trigger trg_updatelog
on student
after update
as
begin
insert into studentlog(studentid, oldname, newname, updatetime)
select d.id, d.name, i.name, getdate()
from deleted d
join inserted i on d.id = i.id
end四、触发器的常见应用场景
1. 数据审计(日志记录)
create trigger trg_insertlog
on orders
after insert
as
begin
insert into orderlog(orderid, createtime)
select id, getdate() from inserted
end2. 数据校验(防止非法数据)
例如:禁止工资为负数
create trigger trg_checksalary
on employee
after insert, update
as
begin
if exists (select 1 from inserted where salary < 0)
begin
rollback
raiserror('工资不能为负数',16,1)
end
end3. 维护关联数据(如库存)
当订单插入时,自动减少库存。
五、触发器的注意事项(非常重要)
1. 触发器是“针对集合”的,不是单行
错误写法(假设只有一行):
select @id = id from inserted
正确思维:要按多行数据处理。
2. 不要在触发器中写复杂业务逻辑
原因:
难调试
性能差
容易造成死锁
影响主业务sql执行
触发器适合做:
✅ 校验
✅ 日志
✅ 简单数据同步
不适合:
❌ 复杂计算
❌ 调用外部接口
❌ 长事务逻辑
3. 谨慎使用 rollback
触发器中一旦 rollback,原 sql 操作也会失败。
4. 注意递归触发
如果触发器中再次修改本表,可能导致无限循环。
可关闭递归:
alter database dbname set recursive_triggers off
六、触发器与存储过程的区别
| 对比项 | 触发器 | 存储过程 |
|---|---|---|
| 是否自动执行 | 是 | 否 |
| 是否可传参 | 否 | 是 |
| 调用方式 | 系统触发 | 手动调用 |
| 使用场景 | 监听数据变化 | 业务逻辑处理 |
七、最佳实践总结
推荐使用场景:
数据审计日志
简单校验规则
防误操作保护
数据同步
不推荐使用场景:
核心业务逻辑
高并发复杂处理
跨系统调用
一句话原则:
触发器 = 数据层的“守门员”,不是业务层的“指挥官”。
八、结语
sql server 触发器是一把“双刃剑”:
用得好:提高数据安全性与一致性
用不好:降低性能、增加维护成本
建议遵循:
少用、慎用、简单用。
把复杂业务逻辑放在:
存储过程
服务层(java / c#)
应用程序中处理
面试回答话术(简洁版)
“触发器主要用于实现复杂的业务完整性、审计日志、自动更新冗余统计字段以及软删除。但我清楚它的代价:隐式执行、难以调试、容易引发性能问题和死锁。
使用时我会特别注意:
基于集合处理 inserted/deleted,绝不用游标或逐行操作;
避免在触发器内进行耗时操作或开启新事务;
关闭递归触发器(除非有明确需求);
对批量操作做充分测试;
优先考虑用约束、计算列或应用层逻辑替代触发器。
总的来说,触发器是最后的手段,能不用就不用;但遇到必须保证数据强一致性且无法用其他方法实现时,它是个有效的工具。”
总结
到此这篇关于sql server触发器常见应用场景和注意事项详解的文章就介绍到这了,更多相关sql server触发器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论