SQL 脚本四

 

 fristly,let's we see a picture:

 

 

 

器是在对表进行插入、更新或删除操作时自动执行的存储过程

触发器通常用于强制业务规则;是一种高级约束,可以定义比用CHECK 约束更为复杂的约束。 可执行复杂的SQL语句(if/while/case)引用其它表中的列

     触发器定义在特定的表上,与表相关
     自动触发执行
     不能直接调用
     是一个事务(可回滚)


触发器触发时:


#系统自动在内存中创建deleted表或inserted表

#只读,不允许修改;触发器执行完成后,自动删除
inserted 表
#临时保存了插入或更新后的记录行
#可以从inserted表中检查插入的数据是否满足业务需求
 # 如果不满足,则向用户报告错误消息,并回滚插入操作
deleted 表
#临时保存了删除或更新前的记录行
#可以从deleted表中检查被删除的数据是否满足业务需求
 # 如果不满足,则向用户报告错误消息,并回滚插入操作

 


语法:
CREATE TRIGGER trigger_name
 ON table_name
 [WITH ENCRYPTION]
  FOR [DELETE, INSERT, UPDATE]
 AS
  T-SQL语句
GO
WITH ENCRYPTION表示加密触发器定义的SQL文本
DELETE, INSERT, UPDATE指定触发器的类型

 

//定义数据库
use classscore
go
if exists (select * from sysobjects where name='tranuser')
 drop table tranuser
if exists (select * from sysobjects where name='traninfo')
 drop table traninfo
go
create table tranuser
(
 ids int not null,
 username char(8) not null,
 moneys money not null
)
go
create table traninfo
(
 cid int not null,
 trantype char(4) not null,
 tranmoney money not null,
 dates datetime not null
)
go
alter table tranuser
 add constraint ck_money check(moneys>=1)
alter table traninfo
 add constraint df_dates default(getdate()) for dates
go
insert into tranuser(ids,username,moneys)values(1,'张三',1000)
insert into tranuser(ids,username,moneys)values(2,'李四',1)
insert into traninfo(cid,trantype,tranmoney)values(1,'支取',200)
select * from tranuser
select * from traninfo
go

 

INSERT触发器-问题:
解决上述的银行取款问题:当向交易信息表(transInfo)中插入一条交易信息时,我们应自动更新对应帐户的余额。


分析:
在交易信息表上创建INSERT触发器
从inserted临时表中获取插入的数据行
根据交易类型(transType)字段的值是存入/支取,
 增加/减少对应帐户的余额。

 

--定义insert触发器
if exists (select * from sysobjects where name='tg_traninfo')
 drop trigger tg_traninfo
go
create trigger tg_traninfo
on traninfo
for insert
as
 declare @uid int,@types char(4),@moneys money
 select @uid=cid,@types=trantype,@moneys=tranmoney
 from inserted
 if (@types='支取')
  update tranuser set moneys=moneys-@moneys where ids=@uid
 else
  update tranuser set moneys=moneys+@moneys where ids=@uid
go


--执行insert触发器
insert into traninfo(cid,trantype,tranmoney)values(1,'支取',300)
select * from tranuser
select * from traninfo

 

DELETE触发器-问题
问题:
当删除交易信息表时,要求自动备份被删除的数据到表backupTable中 。


分析:
在交易信息表上创建DELETE触发器
被删除的数据可以从deleted表中获取

 

--定义delete触发器
if exists(select * from sysobjects where name='tg_infodel')
 drop trigger tg_infodel
go
create trigger tg_infodel
on traninfo
for delete
as
 if not exists (select * from sysobjects where name='tranbak')
  select * into tranbak from deleted
 else
  insert into tranbak select * from deleted
go


--执行delete触发器
delete from traninfo where tranmoney=200
select * from tranbak

 

UPDATE触发器-问题
问题:
跟踪用户的交易,交易金额超过20000元,则取消交易,并给出错误提示。


分析:
在bank表上创建UPDATE触发器
修改前的数据可以从deleted表中获取
修改后的数据可以从inserted表中获取 
               
--定义update触发器
if exists(select * from sysobjects where name='tg_infoup')
 drop trigger tg_infoup
go
create trigger tg_infoup
on tranuser
for update
as
 declare @old money,@new money
 select @old=moneys from deleted
 select @new=moneys from inserted
 if (abs(@new-@old)>20000)
 begin
  print '超过限额!交易失败!'
  rollback transaction
 end
go


--执行update触发器
update tranuser set moneys=moneys+30000 where ids=1
select * from tranuser

 

列级UPDATE触发器
UPDATE触发器除了跟踪数据的变化(修改)外,还可以检查是否修改了某列的数据
使用UPDATE(列)函数检测是否修改了某列


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


分析:
UPDATE(列名)函数可以检测是否修改了某列

 

--定义列级update触发器
if exists(select * from sysobjects where name='tg_infodate')
 drop trigger tg_infodate
go
create trigger tg_infodate
on traninfo
for update
as
 if update(dates)
 begin
  print '不能修改交易时间!'
  rollback transaction
 end
go


--执行列级update触发器
set nocount on --不显示受影响的行数
update traninfo set dates='2001-1-1 00:00:00'
select * from traninfo

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值