触发器、游标

一、触发器

    触发器的两张虚拟表:

    

     Tickets表原始数据:

     

     TicketsOrders表原始数据:

     

   1.插入触发器

      创建

1 create trigger ticketsOrdersInsert
2 on edisondb..ticketsOrders
3 after insert
4  as
5  begin
6 if (select t.currentAmount from tickets as t,inserted
7 where t.ticketid=inserted.ticketid)<
8 (select amount from inserted)
9 begin
10 print '订票数超过库存数,无法订票!'
11 rollback transaction -----将插入操作进行回滚
12   end
13 else
14 print '订票成功!'
15 update tickets set tickets.currentAmount=tickets.currentAmount-inserted.amount
16 from inserted
17 where tickets.ticketid=inserted.ticketid
18  end

     插入非法值:

1 use edisondb;
2
3  insert into ticketsOrders(custid ,ticketid ,amount)
4 values(10001,1,100);
    执行结果:

   2.更新触发器

     创建: 

1create trigger ticketsUpdate
2 on edisondb..Tickets
3 after update
4as
5begin
6 if update(totalAmount)
7 begin
8 if (select totalAmount from deleted)<>(select currentAmount from deleted)
9 begin
10 raiserror('该票已经有人订票,不可更新总票数',16,1)
11 rollback transaction----回滚
12 end
13 end
14end
    更新非法数据: 

1use edisondb;
2update Tickets set tickets.totalAmount=100
3 where ticketid=1;
   执行结果为: 

   3.删除触发器

      创建:

1create trigger ticketsDelete
2 on edisondb..Tickets
3 after delete
4as
5begin
6 if (select totalAmount from deleted)<>(select currentAmount from deleted)
7 begin
8 print '该票已经有人订购,不可删除'
9 rollback transaction----回滚
10 end
11end
      非法删除数据: 

1use edisondb;
2delete from tickets
3where ticketid=1;
      执行结果为: 


二、游标

     游标:行级操作,性能杀手

     SQL查询:数据集操作,速度快(优先选用

    

     使用游标进行操作:(查出每个用户的总运费)

1 set nocount on;
2 use edisondb;
3 declare @startDT datetime
4 set @startDT=getdate()
5 declare @CustomerTotalFreight table
6 (
7 custid numeric(18,0),
8 totalFreight numeric(18,2)
9 );
10 declare
11 @currentCustid as numeric(18,0),
12 @prvCutstid as numeric(18,0),
13 @currentFreight as numeric(18,2),
14 @totalFreight as numeric(18,2);
15 declare customerTotalFreight_cursor cursor for ----声明游标
16 select custid,freight
17 from orders
18 order by custid;
19 open customerTotalFreight_cursor ----打开游标
20 ----循环获取每行记录
21 fetch next from customerTotalFreight_cursor into @currentCustid,@currentFreight;
22 select @prvCutstid=@currentCustid,@totalFreight=0.00;
23 while @@fetch_status=0
24 begin
25 if @prvCutstid<>@currentCustid
26 begin
27 insert into @CustomerTotalFreight values(@prvCutstid,@totalFreight);
28 select @prvCutstid=@currentCustid,@totalFreight=@currentFreight;
29 end
30 else
31 begin
32 set @totalFreight=@totalFreight+@currentFreight;
33 end
34 fetch next from customerTotalFreight_cursor into @currentCustid,@currentFreight;
35 end;
36 insert into @CustomerTotalFreight values(@prvCutstid,@totalFreight);
37 close customerTotalFreight_cursor; ----关闭游标
38
39 deallocate customerTotalFreight_cursor;----释放游标
40
41 select * from @CustomerTotalFreight order by custid;
42
43 print '耗时:'+replace(str(datediff(ms,@startDT,getdate())),' ','')+' 毫秒'
   执行结果为:

  

   以上功能如果用SQL查询来实现则十分简洁:

1 use edisondb;
2 declare @startDT datetime
3 set @startDT=getdate()
4 select custid,sum(freight) as totalFreight
5 from orders
6 group by custid;
7 print '耗时:'+replace(str(datediff(ms,@startDT,getdate())),' ','')+' 毫秒'
   执行结果为:

  

原文地址:https://www.cnblogs.com/edisonfeng/p/2102672.html