触发器、游标

一、触发器

    触发器的两张虚拟表:

     触发器、游标

     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.更新触发器

     创建: 

   
     
1 create trigger ticketsUpdate
2 on edisondb..Tickets
3 after update
4 as
5 begin
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
14 end
    更新非法数据:  

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

   3.删除触发器

      创建:

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

   
     
1 use edisondb;
2 delete from tickets
3 where 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 ())), ' ' , '' ) + ' 毫秒 '
   执行结果为:

   触发器、游标

你可能感兴趣的:(触发器)