大部分参考自:https://www.cnblogs.com/wangprince2017/p/7827091.html
一、触发器的简介:
触发器(trigger)是SQL server 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对一个表进行操作( insert,delete, update)时就会激活它执行。
二、触发器的作用:
触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂参照完整性和数据的一致性,它能够对数据库中的相关表进行级联修改,提高比CHECK约束更复杂的的数据完整性,并自定义错误消息。触发器的主要作用主要有以下接个方面:
- 强制数据库间的引用完整性
- 级联修改数据库中所有相关的表,自动触发其它与之相关的操作
- 跟踪变化,撤销或回滚违法操作,防止非法修改数据
- 返回自定义的错误消息,约束无法返回信息,而触发器可以
- 触发器可以调用更多的存储过程
三、触发器的分类:
按触发事件的不同,sqlserver可分成三种不同的触发器,DML触发器,DDL触发器,登录触发器
1. DML(Data Manipulation Language)触发器
DML触发器是一些附加在特定表或视图上的操作代码,当数据库服务器中发生数据操作语言事件时执行这些操作。SqlServer中的DML触发器有三种:
- insert触发器:向表中插入数据时被触发;
- delete触发器:从表中删除数据时被触发;
- update触发器:修改表中数据时被触发。
使用情况:
- 防止恶意或者错误的insert、update和delete操作,并强制执行check约束定义的限制更为复杂的其他限制。
- 通过数据库中的相关表实现级联更改
- 评估数据修改前后表的状态,并根据该差异才去措施。
2. DDL(数据定义语言,Data Definition Language)触发器
DDL触发器是当服务器或者数据库中发生数据定义语言(主要是以create,drop,alter开头的语句)事件时被激活使用,主要作用是执行管理操作,例如审核系统、控制数据库的操作等。
3. 登录触发器:
登录触发器将为响应 LOGIN 事件而激发存储过程。与 SQL Server 实例建立用户会话时将引发此事件。登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。因此,来自触发器内部且通常将到达用户的所有消息(例如错误消息和来自 PRINT 语句的消息)会传送到 SQL Server 错误日志。如果身份验证失败,将不激发登录触发器。
三、DML触发器工作原理
注意:
- 系统自动在内存中创建deleted表或inserted表;
- 只读,不允许修改,触发器执行完成后,自动删除。
四、创建DML触发器
创建触发器语法:
CREATE TRIGGER trigger_name
ON table_name
[WITH ENCRYPTION]
FOR | AFTER | INSTEAD OF [DELETE, INSERT, UPDATE]
AS
T-SQL语句
GO
--with encryption 表示加密触发器定义的sql文本
--delete,insert,update指定触发器的类型
1. 创建INSERT触发器
CREATE TRIGGER trig_transInfo
ON transInfo
FOR INSERT
AS
DECLARE @type char(4),@outMoney MONEY
DECLARE @myCardID char(10),@balance MONEY
SELECT @type=transType,@outMoney=transMoney,
@myCardID=cardID FROM inserted --从inserted表中获取交易类型、交易金额等
IF (@type='支取')
UPDATE bank SET currentMoney=currentMoney- @outMoney WHERE cardID=@myCardID
ELSE
UPDATE bank SET currentMoney = currentMoney + @outMoney WHERE cardID=@myCardID
--根据交易类型,减少或增加对应卡号的余额
GO
2. 创建UPDATE触发器
CREATE TRIGGER trig_update_bank
ON bank FOR UPDATE
AS
DECLARE @beforeMoney MONEY,@afterMoney MONEY
--从deleted表中获取交易前的余额,从inserted表中获取交易后的余额
SELECT @beforeMoney=currentMoney FROM deleted
SELECT @afterMoney=currentMoney FROM inserted
IF ABS(@afterMoney-@beforeMoney)>20000
BEGIN
print '交易金额:'+convert(varchar(8),
ABS(@afterMoney-@beforeMoney))
RAISERROR ('每笔交易不能超过2万元,交易失败',16,1)
ROLLBACK TRANSACTION --回滚事务,撤销交易
END
GO
3. 创建DELETE触发器
CREATE TRIGGER trig_delete_transInfo
ON transInfo
FOR DELETE
AS
print '开始备份数据,请稍后......'
IF NOT EXISTS(SELECT * FROM sysobjects
WHERE name='backupTable')
SELECT * INTO backupTable FROM deleted
ELSE
INSERT INTO backupTable
SELECT * FROM deleted
print '备份数据成功,备份表中的数据为:'
SELECT * FROM backupTable
GO
4. INSTEAD OF触发器(触发方式不同)
以上介绍的全为AFTER触发器,首先FOR和AFTER是完全相同的,SqlServer服务器在执行AFTER触发器的sql代码后,先建立临时的inserted表和deleted表,然后执行代码中对数据库操作,最后才激活触发器中的代码,如果要撤销前面执行的sql语句,可以在触发器中执行回滚操作。而对于替代INSTEAD OF,SqlServer服务器在执行触发INSTEAD OF触发器的代码时,先建立临时的inserted表和deleted表,然后直接触发INSTEAD OF触发器,而不执行用户输入的SQL语句。
--创建instead of 触发器
create trigger trig_insteadOf
on student
instead of insert
as
begin
declare @stuAge int;
select @stuAge=(select stu_age from inserted)
if(@stuAge >120)
select '插入年龄错误' as '失败原因'
end
5. 嵌套触发器
6. 递归触发器
五、触发器的管理