SQL SERVER触发器(附有实例)

触发器即当发生某一事件时,如果满足给定条件,则执行相应的动作。

它的基本架构:

  

触发器创建语法:

(1)

CREATETRIGGER trigger_name

ON table|view

FOR|AFTER|INSTEADOF [DELETE][,INSERT][,UPDATE]

AS

Sql_statement[…n]

(2)

CREATETRIGGER trigger_name

ON table|view

FOR|AFTER|INSTEADOF [DELETE][,INSERT][,UPDATE]

AS

IFUPDATE(column)

[{AND|OR}UPDATE(COLUMN)][…]

IF(COLUMNS_UPDATED())

Sql_statement[…n]

注:(不同数据库支持不同的类型触发器,有些还支持before类型触发器,像SQL server 就不支持before触发器)

SQL Server 支持两种类型的触发器AFTER 触发器和INSTEAD OF 触发器,其中、

AFTER 触发器要求只有执行某一操作ISERT, UPDATE ,DELETE 之后触发器才被触

发。

1)INSTEAD OF 触发器表示并不执行其所定义的操作INSERT,UPDATE ,DELETE,而

仅是执行触发器本身,既可在表上定义INSTEAD OF 触发器,也可以在视图上定

INSTEAD OF 触发器。

2)after  触发器(也叫“FOR”触发器)则会在触发 insert、update 或是delect 动作之

后执行。

触发事件分为三类:UPDATEDELETEINSERT。

另外,定义触发器时,系统都都会自动生成两张表,我们是可以直接用的,如下:

如下是实例(都是亲手实践过的):

可在这里下载数据库文件,下面实例以这个数据库为例子

我想改为0的但改不了,小伙伴可以参照便文章免费下载

也可以用百度网盘了:链接:https://pan.baidu.com/s/1gtlSrhQSBAd1rblrmU3JiA  提取码:q79b 
 

1.在表Student中建立删除触发器,实现表Student和表SC的级联删除,也就是只要删除表Student
中的元组学号为s1,则表SC中SNO为s1的元组也要删除;建立完触发器后用企业管理器删除Student中学号
为30的元组,看看表SC中SNO为30的选课记录是否也一起删除;

create trigger t_std2 on student
instead of  delete
as
begin
  declare @id char(5)
  select @id=sno from deleted
  delete from sc where SNo =@id
  delete from student where SNo=@id
  end
  go

delete from Student where SNo='00002'

/*2.	在表Course中增加一个职业规划选修课,为(005,职业规划,4,0014),在表SC中建立一个触发器,
实现规定年龄24岁以上(包括24岁)的学生才能选修职业规划这门课程,如果年龄小于24岁,则输出’
年龄小于24,不能选修该门课程’,插入失败,用SQL语句在SC表中分别插入(‘00001’,’005’,null)和
(‘00005’,’005’,null)看看结果;**/
create trigger t_sc on sc
for insert
as
begin
  declare @id char(5)
  select @id=sno from inserted
  if((select cno from inserted)='005' and (select sage from student where SNo= @id )<24)
  begin
  print '年龄小于24,不能选修该门课程 '
  rollback transaction
  end
  else
   print 'nice!'
   end
insert into course values('005','职业规划','4','0014')
insert into sc values('00001','005',null)
insert into sc values('00005','005',null)
select * from sc
go
 
3.在表SC中建立更改触发器,实现表SC中的修改后的成绩不能低于修改前的成绩,
如果修改后的成绩低于修改前的成绩,则输出’修改后的成绩比修改前低,不能修改’,
修改失败,用SQL语句把学号为00001,课程号为001的成绩分别改为90和70,看看结果;
 

createtrigger t2_sc on sc

after update

as

if(update(score))

begin

  declare @score1 numeric(3,1),@score2numeric(3,1)

  select @score1=score from inserted

  select @score2=score from deleted

  if(@score1>@score2 )

   print 'nice! '

   else

    update sc

    set sc.Score=@score2 from sc,deleted

    where sc.SNo=deleted.SNo andsc.CNo=deleted.CNo

    print '失败'

    end

update sc

    setScore=70 where SNo='00001' and CNo='001'

 
4.	在表Teacher中创建触发器,实现如果更新了表Teacher中的年龄和工资,
则输出’更新了年龄和工资’,如果更新了年龄没有更新工资,则输出’更新了年龄’,
如果更新了工资而没有更新年龄,则输出’更新了工资’,创建完后使用SQL语句把
tno为001的年龄加1,把tno为002的工资加1,把tno为003的年龄和工资都加1,看看结果;
create trigger t_teacher on teacher
after update
as
begin
  declare @age int,@sal float
  select @age=age from deleted
  select @sal=sal from deleted
  if(@age <> (select age from inserted )and @sal <>(select sal from inserted))
  print '更新了年龄和工资 '
  else if(@age <> (select age from inserted )and @sal =(select sal from inserted))
  print '更新了工资 '
  else if(@age = (select age from inserted )and @sal <>(select sal from inserted))
   print '更新了年龄 '
   end

   update Teacher
   set age=age+1 where Tno='0001'**/
/**
5.	在不删除触发器的前提下,使3创建的触发器无效;
alter table teacher disable trigger t_teacher**/

/**
6.	创建一个名为tri_Delete_C的触发器,要求首先判断数据库中是否已经存在名为tri_Delete_C的触发器,
如果存在,首先删除,再创建,触发器要求删除一门课程时候,首先判断该课程有否有人选,如果有人选,
则不能删除,并通过测试数据验证该触发器的执行情况。**/
if(exists (select * from  sysobjects where xtype='tr' and name='tri_Delete_C'))
begin
  drop trigger tri_Delete_C
  print '已删除'
  end
  go
  create trigger tri_Delete_C on course
   for delete
    as	
	begin
	if exists (select * from sc inner join deleted on sc.CNo=deleted.CNo)
	begin
	  print '不能删除'
	  rollback transaction
	end
	end
	go
	alter table sc drop constraint FK__sc__CNo__08B54D69
	delete course where CNo='001'
	alter table sc add constraint FK__sc__CNo__08B54D69 foreign key(cno) references course(cno) 

sqlserver触发器例子 一﹕ 触发器是一种特殊的存储过程﹐它不能被显式地调用﹐而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。所以触发器可以用来实现对表实施复杂的完整性约`束。 二﹕ SQL Server为每个触发器都创建了两个专用表﹕Inserted表和Deleted表。这两个表由系统来维护﹐它们存在于内存中而不是在数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行 完成后﹐与该触发器相关的这两个表也被删除。 Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。 Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。 三﹕Instead of 和 After触发器 SQL Server2000提供了两种触发器﹕Instead of 和After 触发器。这两种触发器的差别在于他们被激活的同﹕ Instead of触发器用于替代引起触发器执行的T-SQL语句。除表之外﹐Instead of 触发器也可以用于视图﹐用来扩展视图可以支持的更新操作。 After触发器在一个Insert,Update或Deleted语句之后执行﹐进行约束检查等动作都在After触发器被激活之前发生。After触发器只能用于表。 一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器﹐一个表的每个修改动作都可以有多个After触发器。 四﹕触发器的执行过程 如果一个Insert﹑update或者delete语句违反了约束﹐那幺After触发器不会执行﹐因为对约束的检查是在After触发器被激动之前发生的。所以After触发器不能超越约束。 Instead of 触发器可以取代激发它的操作来执行。它在Inserted表和Deleted表刚刚建立﹐其它任何操作还没有发生时被执行。因为Instead of 触发器在约束之前执行﹐所以它可以对约束进行一些预处理。 五﹕使用T-SQL语句来创建触发器 基本语句如下﹕ create trigger trigger_name on {table_name | view_name} {for | After | Instead of } [ insert, update,delete ] as sql_statement 六﹕相关示例﹕ 1﹕在Orders表中建立触发器﹐当向Orders表中插入一条订单记录时﹐检查goods表的货品状态status是否为1(正在整理)﹐是﹐则不能往Orders表加入该订单。 create trigger orderinsert on orders after insert as if (select status from goods,inserted where goods.name=inserted.goodsname)=1 begin print 'the goods is being processed' print 'the order cannot be committed' rollback transaction --回滚﹐避免加入 end 2﹕在Orders表建立一个插入触发器﹐在添加一条订单时﹐减少Goods表相应的货品记录中的库存。 create trigger orderinsert1 on orders after insert as update goods set storage=storage-inserted.quantity from goods,inserted where goods.name=inserted.goodsname 3﹕在Goods表建立删除触发器﹐实现Goods表和Orders表的级联删除。 create trigger goodsdelete on goods after delete as delete from orders where goodsname in (select name from deleted) 4﹕在Orders表建立一个更新触发器﹐监视Orders表的订单日期(OrderDate)列﹐使其不能手工修改. create trigger orderdateupdate on orders after update as if update(orderdate) begin raiserror(' orderdate cannot be modified',10,1) rollback transaction end 5﹕在Orders表建立一个插入触发器﹐保证向Orders表插入的货品名必须要在Goods表中一定存在。 create trigger orderinsert3 on orders after insert as if (select count(*) from goods,inserted where goods.name=inserted.goodsname)=0 begin print ' no entry in goods for this order' rollback transaction end --insert 触发器 create trigger tri_infoDetails_i on info_details after insert as declare @id int begin --delete from info_details where id= select @id=id from inserted; insert into info_details_index(TYPE,TITLE,content,POST_TIME,FLAG) select type,title,content,getdate(),1 from info_details where id=@id; --update info_details_index set content=content end; -- update触发器 --select top 0 type,title,content,getdate() as post_time,1 as flag into info_details_index from info_details; create trigger tri_infoDetails_u on info_details after update as declare @id int begin if exists(select 1 from inserted) if exists(select 1 from deleted) begin select @id=id from inserted; insert into info_details_index(TYPE,TITLE,content,POST_TIME,FLAG)select type,title,content,getdate(),-1 from info_details where id=@id; insert into info_details_index(TYPE,TITLE,content,POST_TIME,FLAG)select type,title,content,getdate(),1 from info_details where id=@id; end --update info_details_index set content=content end --delete触发器 create trigger tri_infoDetails_d on info_details after delete as declare @id int begin if exists(select 1 from deleted) begin insert into info_details_index(TYPE,TITLE, POST_TIME,FLAG) select type,title, getdate(),-1 from deleted info_details ; end end
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

legendaryhaha

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值