您的位置:首页 > 数据库

SQL SERVER触发器应用案例讲解(deleted表或者inserted表)

2015-01-08 20:01 423 查看
1、触发器触发时:

a、系统自动在内存中创建deleted表或者inserted表

b、只读,不允许修改;触发器执行完成后,自动删除

2、inserted表

a、临时保存了插入或更新后的记录行

b、可以从inserted表中检查插入的数据是否满足业务需求

c、如果不满足,则向用户报告消息错误,并回滚插入操作

3、deleted表

a、临时保存了删除或更新前的记录行

b、可以存deleted表中检查删除的数据是否满足业务

c、如果不满足,则向用户报告错误消息,并回滚插入操作

4、关于inserted与deleted表的说明



创建触发器的语法:

Create trigger trigger_name

on {table_name|view}

[with encryption]

{

{{FOR|AFTER|INSTEAD OF}{ [delete,insert,update] [ , ] [UPDATE]}

[WITH APPEND]

[NOT FOR REPLICATION]

AS

[ { IF UPDATE (column) [{AND | OR} UPDATE (column)] |

IF (COLUMNS_UPDATED ())}]

t-sql语句

go

}

Table_name|view

是在其上执行触发器的表或视图,有时称触发器表或触发器视图。可以选择是否指定表或视图所有者的名称

with encryption表示加密触发器定义的sql文本

加密syscomments 表中包含Create trigger语句文本的条目,使用With Encryption可以防止将触发器作为SQL SERVER复制的一部分发布

AFTER

指定触发器只有在触发SQL语句中指定的所有操作都已成功后才激发,所有的应用级联操作和约束检查也必须完成后,才能执行次触发器。

如果仅指定FOR关键子,则AFTER是默认值。

不能再视图上定义AFTER触发器

INSTEAD OF

指定执行触发器而不是执行触发SQL语句,从而替代触发语句的操作

在表或视图上,每个INSERT、UPDATE或DELETE语句最多定义一个INSERT OF 触发器,然而可以在每个具有INSTEAD OF触发器的视图上定义视图。

INSERT OF触发器不能再WITH CHECK OPTION的可更新视图上定义,如果指向了WITH CHECK OPTION 选项的可更新视图添加INSERT OF触发器,SQL SERVER将产生一个错误,用户必须用Alter View删除该选项后才能定义INSTEAD OF 触发器.

{[delete] [,] [insert] [,] [update]}

是指定在表或视图上执行那些数据修改语句时将激活触发器的关键子,必须至少指定一个选项,在触发器定义中允许使用一任意顺序组合的这些关键字,如果指定的选项多于一个,需要逗号分隔这些选项。

对于INSERT OF触发器,不允许在具有ON DELETE级联操作引用关系的表上使用DELETE选项,同样,也不允许在具有ON UPDATE级联操作引用关系的表上使用UPDATE选项。

delete,insert,update指定触发器的类型

示例1、insert触发器

insert触发器的工作原理



问题:解决上述的银行取款问题,单向交易信息表(transinfo)中插入一条交易信息时,我们应自动更新对应账号的余额。

分析:

在交易表上创建insert触发器

从inserted临时表中获取插入的数据行

根据交易类型(Transtype)自动的值是存入/支取

增加/减少对应账号的余额

create trigger trig_transinfo

on transinfo

for insert

as

declare @type varchar(4),@outmoney money

declare @mycardid varchar(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=currentmoney+@outmoney where cardid=@mycardid

示例2、

create trigger trig_transInfo

on TTotal

for insert

as

declare @year varchar(100)

select @year=年份 from inserted

if(@year='2007')

rollback transaction

2、delete触发器

delete触发器的工作原理:



问题:单删除交易信息表时,要求自动备份被删除的数据到表的backuptable中

分析:

在交易信息表上创建delete触发器

被删除的数据可以从deleted表中获取

create trigger trig_delete_info

on transinfo

for delete

as

print '开始备份数据,请稍后.....'

if not exists(select * from sysobjects where name='bakcuptable')

select * into backuptable from deleted

else

insert into backuptable select * from deleted

print '备份数据成功,备份表中的数据为:'

select * from backuptable

go

案例2,员工退休将员工信息存员工表删除,然后存入退休人员表

create trigger trig_delete_transinfo

on Employees

for delete

as

print '开始备份数据,请稍后...'

if not exists(select * from sysobjects where name='backuptable')

select * into backuptable from deleted

else

insert into backuptable select UserName,SSex from deleted

print '备份数据成功,备份表中的数据为'

select * from backuptable

go

3、update触发器,

update触发器的工作原理:



问题跟踪用户的交易,交易额超过20000元,则取消交易,并给出错误提示

分析:

在bank表中创建update触发器

修改前的数据可以从deleted表中获取

修改后的数据可以从inserted表中获取

create trigger trig_update_bank

on bank

for update

as

declare @beforemoney money,@aftermoney money

select @beforemoney=currentmoney from deleted

select @aftermoney=currentmoney from inserted

if abs(@aftermoney-@beforemoney)>2000

begin

print '交易金额:'+convert(varchar(100),abs(@aftermoney-@beforemoney))

raiserror('每笔交易不能超过2万元,交易失败',16,1)

rollback transaction

end

go

执行:

update bank set currentmoney=currentmoney+200001 where ID=1

列级Update触发器

update 触发器除了跟踪数据的变化(修改)外,还可以检查是否修改了某列的数据

使用update(列)函数检测是否修改了某列

问题:

交易日期一般有系统自动产生,默认为当前日期,为了安全起见,一般禁止修改,以防舞弊

分析:

update(列名)函数可以检测是否修改了某列

create trigger trig_update _transinfo

on transInfo

for update

as

if update(transdate)

begin

print '交易失败......'

RAISERROR('安全警告,交易日期不能修改,有系统自动产生',16,1)

rollback transaction

end

go

4、instead of触发器

create trigger trig_ttotal

on sc

instead of insert

as

begin

insert into TT Values('2007','郑州','zb3',12,3)

end

当在sc表中插入一条记录时,不执行在sc表中插入记录,执行你指定的操作

insert into sc(courseid,studentid,grade) values(1,12,90),

instead of 触发器的用法

INSTEAD OF 触发器的主要优点是可以使不能更新的视图支持更新。基于多个基表的视图必须使用

INSTEAD OF 触发器来支持引用多个表中数据的插入、更新和删除操作。INSTEAD OF 触发器的另一个优点是使您得以编写这样的逻辑代码:在允许批处理的其他部分成功的同时拒绝批处理中的某些部分。

Transact-SQL 语句创建两个基表、一个视图和视图上的 INSTEAD OF 触发器。以下表将个人数据和业务数据分开并且是视图的基表。

--部门表

create table dept

(

d_id int primary key,

d_name varchar(20)

)

--员工表

create table emp

(

e_id int primary key,

e_name varchar(20),

d_id int references dept(d_id)

)

select * from emp

drop view v

create view v

as

select e_id,e_name,d.d_id,d_name from emp e,dept d where e.d_id=d.d_id

select * from v

insert into v values(1001,'张珊',101,'销售部')

drop trigger de_em_insert

go

create trigger de_em_insert

on v

instead of insert

as

begin

if (not exists (select d.d_id from dept d, inserted i where d.d_id = i.d_id))

insert into dept select d_id,d_name from inserted

if (not exists (select e.d_id from emp e, inserted i where e.d_id = i.d_id))

insert into emp select e_id,e_name,d_id from inserted

else

update emp set e_id = i.e_id,e_name = i.e_name from emp e, inserted i where e.d_id = i.d_id

end

可以在视图或表中定义 INSTEAD OF DELETE 触发器,以代替 DELETE 语句的标准操作。通常,在视图上定义 INSTEAD OF DELETE 触发器以便在一个或多个基表中修改数据。

可在视图上定义 INSTEAD OF UPDATE 触发器以代替 UPDATE 语句的标准操作。通常,在视图上定义 INSTEAD OF UPDATE 触发器以便修改一个或多个基表中的数据。

触发器是在对表进行插入、更新或删除操作时自动执行的存储过程,触发器通畅用于强制业务规则

触发器是一个特殊的事务单位,当出现错误是,可以执行rollback transaction回滚撤销操作

触发器一般都需要使用临时表,deleted和inserted表,他们存放被删除或插入记录的副本

触发器类型:insert触发器、update触发器、delete触发器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: