• 触发器、游标


    一、触发器

        触发器的两张虚拟表:

        

         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())),' ','')+' 毫秒'
       执行结果为:

      

  • 相关阅读:
    计算机
    产品经理
    Vue router-link路由不同的写法,不一样的效果
    elementui样式引入方法
    格式化启动盘win10
    删除mongdb中的数据库
    google浏览器快速清除历史记录
    js动画之弹球打砖块小游戏
    js动画之面向对象二
    js动画之面向对象一
  • 原文地址:https://www.cnblogs.com/edisonfeng/p/2102672.html
Copyright © 2020-2023  润新知