1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,*,SQL,触发器,2,本章目标,了解为什么需要触发器,理解触发器的工作原理,掌握如何使用,inserted,表和,deleted,表,掌握如何创建:,INSERT,触发器,UPDATE,触发器,DELETE,触发器,3,为什么需要触发器,(TRIGGER),呢?典型的应用就是银行的取款机系统,为什么需要触发器,演示:为什么需要触发器,.sql,帐户信息表,bank,交易信息表,transInfo,张三取钱,200,问题:,没有,自动修改,张三的余额,最优的解决方案就是采用,触发器:,它是一种特殊的存储过程,也具备事务的功能,
2、它能在多表之间执行特殊的业务规则,张三开户,1000,元,李四开户,1,元,4,张三,李四,王五,赵二,王三,宋二,刘五,插入,什么是触发器,3-1,删除,触发器触发,赵二退休,赵二,员工表,退休员工表,5,触发器是在对表进行插入、更新或删除操作时,自动执行的存储过程,触发器通常用于强制业务规则,触发器是一种,高级约束,,可以定义比用,CHECK,约束更为复杂的约束,可执行复杂的,SQL,语句(,if/while/case,),可引用其它表中的列,什么是触发器,3-2,6,触发器定义在特定的表上,与表相关,自动触发执行,不能直接调用,是一个事务(可回滚),什么是触发器,3-3,7,触发器的类型
3、DELETE,触发器,INSERT,触发器,UPDATE,触发器,8,触发器触发时,:,系统自动在内存中创建deleted表或inserted表,只读,不允许修改,;,触发器执行完成后,自动删除,inserted,表,临时保存了插入或更新后的记录行,可以从,inserted,表中检查插入的数据是否满足业务需求,如果不满足,则向用户报告错误消息,并回滚插入操作,deleted,表,临时保存了删除或更新前的记录行,可以从,deleted,表中检查被删除的数据是否满足业务需求,如果不满足,则向用户报告错误消息,并回滚插入操作,inserted,和,deleted,表,2-1,9,inserted,
4、和,deleted,表,2-2,修改操作,inserted,表,deleted,表,增加,(INSERT),记录,存放新增的记录,-,删除,(DELETE),记录,-,存放被删除的记录,修改,(UPDATE),记录,存放更新后的记录,存放更新前的记录,inserted,表和,deleted,表存放的信息,10,创建触发器的语法:,如何创建触发器,CREATE TRIGGER,t,rigger_name,ON,table,_name,WITH ENCRYPTION,FOR,DELETE,INSERT,UPDATE,AS,T-SQL,语句,GO,WITH ENCRYPTION,表示加密触发器定义的
5、SQL,文本,DELETE,INSERT,UPDATE,指定触发器的类型,11,INSERT,触发器,transInfo,cardID,transType transMoney,1001 0002,1001 0002,存入,300,存入,500,inserted,cardID,transType transMoney,1001 0001,支取,200,transInfo,cardID,transType transMoney,1001 0002,1001 0002,存入,300,存入,500,1001 0001,支取,200,插入记录行,触发,insert,触发器。向,inserted,表中
6、插入新行的副本,触发器检查,inserted,表中插入的新行数据,确定是否需要回滚或执行其他操作,INSERT,触发器的工作原理:,12,INSERT,触发器示例,3-1,问题:,解决上述的银行取款问题:当向交易信息表,(transInfo),中插入一条交易信息时,我们应自动更新对应帐户的余额,。,分析:,在交易信息表上创建,INSERT,触发器,从,inserted,临时表中获取插入的数据行,根据交易类型,(,transType,),字段的值是存入,/,支取,,增加,/,减少对应帐户的余额。,13,-,关键代码,-,CREATE TRIGGER,trig_transInfo,ON,trans
7、Info,FOR INSERT,AS,DECLARE type char(4),outMoney MONEY,DECLARE myCardID char(10),balance MONEY,SELECT type=transType,outMoney=transMoney,,,myCardID=cardID FROM,inserted,IF(type=,支取,),UPDATE bank SET currentMoney=currentMoney-outMoney,WHERE cardID=myCardID,ELSE,UPDATE bank SET currentMoney=currentMon
8、ey+outMoney,WHERE cardID=myCardID,.,GO,INSERT,触发器示例,3-2,从,inserted,表中获取交易类型、交易金额等,根据交易类型,减少或增加对应卡号的余额,14,INSERT,触发器示例,3-3,例:,1,)执行插入语句:,insert into transinfo(transdate,cardid,transtype,transmoney),values(GETDATE(),10010001,支取,300),结果:,Bank,表中相应帐号余额减少,300,;,2,)执行插入语句:,insert into transinfo(transdate,
9、cardid,transtype,transmoney),values(GETDATE(),10010001,存入,2,00),结果:,Bank,表中相应帐号余额增加,200,;,15,transInfo,cardID,transType transMoney,1001 0002,1001 0002,存入,300,存入,500,1001 0001,支取,200,DELETE,触发器,transInfo,cardID,transType transMoney,1001 0002,1001 0002,存入,300,存入,500,deleted,cardID,transType transMoney
10、1001 0001,支取,200,删除记录行,触发,delete,触发器向,deleted,表中插入被删除的副本,触发器检查,deleted,表中被删除的数据,决定是否需要回滚或执行其他操作,DELETE,触发器的工作原理:,16,问题:,当删除交易信息表时,要求自动备份被删除的数据到表,backupTable,中。,分析:,在交易信息表上创建,DELETE,触发器,被删除的数据可以从,deleted,表中获取,DELETE,触发器示例,3-1,17,-,关键代码,-,CREATE TRIGGER trig_delete_transInfo,ON transInfo,FOR DELETE,A
11、S,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,从,deleted,表中获取被删除的交易记录,DELETE,触发器示例,3-2,18,Deleted,(更新前的数据),customerName,cardID c
12、urrentMoney,李四,1000 0002 1,bank,customerName,cardID,currentMoney,张三,10010001 1000,李四,10000002 1,UPDATE,触发器,删除记录行,向,deleted,表中插入被删除的副本,检查,deleted,和,inserted,表中的数据,确定是否需要回滚或执行其他操作,UPDATE,触发器的工作原理:,李四,10000002 20001,向,inserted,表中插入被添加的副本,Inserted,(更新后的数据),customerName,cardID currentMoney,李四,1000 0002 2
13、0001,插入记录行,19,问题:,跟踪用户的交易,交易金额超过,20000,元,则取消交易,并给出错误提示。,分析:,在,bank,表上创建,UPDATE,触发器,修改前的数据可以从,deleted,表中获取,修改后的数据可以从,inserted,表中获取,UPDATE,触发器示例,3-1,20,-,关键代码,-,CREATE TRIGGER,trig_update_bank,ON,bank,FOR UPDATE,AS,DECLARE beforeMoney MONEY,afterMoney MONEY,SELECT beforeMoney=currentMoney FROM,deleted
14、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,从,deleted,表中获取交易前的余额,从,inserted,表中获取交易后的余额,UPDATE,触发器,3-2,交易金额是否,2,万,回滚事务,撤销交易,21,UPDATE
15、触发器,3-3,例:,1,)执行插入语句:,insert into transinfo(transdate,cardid,transtype,transmoney),values(GETDATE(),10010001,存入,2,00),结果:,Bank,表中相应帐号余额增加,200,;,2,)执行插入语句:,insert into transinfo(transdate,cardid,transtype,transmoney),values(GETDATE(),10010001,存入,2,0,0,0,1,),结果:交易失败;,22,列级,UPDATE,触发器,3-1,UPDATE,触发器除了
16、跟踪数据的变化(修改)外,还可以检查是否修改了某列的数据,使用,UPDATE,(列)函数检测是否修改了某列,问题:,交易日期一般由系统自动产生,默认为当前日期。为了安全,起见,一般禁止修改,以防舞弊。,分析:,UPDATE,(列名)函数可以检测是否修改了某列,23,-,关键代码,-,CREATE TRIGGER trig_update_transInfo,ON transInfo,FOR UPDATE,AS,IF,UPDATE,(transDate),BEGIN,print,交易失败,.,RAISERROR(,安全警告:交易日期不能修改,,由系统自动产生,16,1),ROLLBACK TRANSACTION,END,GO,检查是否修改了交易日期列,transDate,回滚事务,撤销交易,列级,UPDATE,触发器,3-2,24,触发器是在对表进行插入、更新或删除操作时自动执行的存储过程,触发器通常用于强制业务规则,触发器还是一个特殊的事务单元,当出现错误时,可以执行,ROLLBACK TRANSACTION,回滚撤销操作,触发器一般都需要使用临时表:,deleted,表和,inserted,表,它们存放了被删除或插入的记录行副本,触发器类型:,INSERT,触发器,UPDATE,触发器,DELETE,触发器,总结,






