• 存储过程,游标,异常捕捉 try catch 实例代码


    大笑

    1.存储过程代码。  (数据库是 AdventureWorks)

    存储过程用来将错误信息插入到指定的表中。

    在别的地方可以调用存储过程插入错误信息(下面部分代码 生成一个表,如果表已经存在就会插入错误信息到表中)

    知识点: try catch,output参数;begin try..end try;begin catch….end catch;

    --存储过程output, begin try,begin catch
    
    
    
    
    
    --声明一个存储过程 uspLogErrorTest  模仿 uspLogError.用来记录发生错误的信息,并将错误信息
    
    --放入到  select * from  [dbo].[ErrorLog]
    
    
    
    create proc dbo.uspLogErrorTest
    
        @ErrorLogID [int]=0 output
    
        
    
    AS
    
    BEGIN
    
        set nocount on
    
        
    
        --输出参数
    
        set @ErrorLogID=0;
    
        
    
        Begin Try
    
            if error_number() is null     --捕捉错误号,有就激活catch
    
                return;
    
            
    
            --当前请求具有活动的用户事务,但出现了致使事务被归类为无法提交的事务的错误。
    
            --请求无法提交事务或回滚到保存点;它只能请求完全回滚事务。请求在回滚事务之前无法执行任何写操作。请求在回滚事务之前只能执行读操作。事务回滚之后,请求便可执行读写操作并可开始新的事务。
    
    
    
            if xact_state()=-1 
    
            begin 
    
                print 'Cannot log error since the current transaction is in an uncommittable state'
    
                      +' Rollback the transaction before executing uspLogError2 in order to successfully log error information'
    
                return;
    
            end
    
            
    
            insert [dbo].[ErrorLog]
    
                (
    
                  [UserName],
    
                  [ErrorNumber],
    
                  [ErrorSeverity],
    
                  [ErrorState],
    
                  [ErrorProcedure],
    
                  [ErrorLine],
    
                  [ErrorMessage]
    
            
    
                )          
    
            values
    
                (
    
                 convert(sysname,current_user),
    
                 error_number(),
    
                 error_severity(),
    
                 error_state(),
    
                 error_procedure(),
    
                 error_line(),
    
                 error_message()
    
                
    
                
    
                );
    
                
    
                
    
                --得到刚才插入的行号
    
                
    
                set @ErrorLogID=@@IDENTITY;
    
        end try
    
        begin catch
    
            print 'an error occurred in stored procedure uspLogError : '
    
            exec   [dbo].[uspprinterror];
    
            return -1;
    
        end catch
    
    end
    
    
    
    --select * from  [dbo].[ErrorLog]
    
    
    
    
    
    
    
    --上面声明存储过程
    
    
    
    --下面调用存储过程,创建表,如果已经存在就会写入表 [dbo].[ErrorLog]
    
    use AdventureWorks
    
    go
    
    begin try
    
        create table OurIFTest(
    
            coll int primary key
    
        )
    
    end try
    
    
    
    begin catch
    
        --something wrong
    
        
    
        declare @MyOutputParameter int;
    
        
    
        if error_number()=2714    --object 存在的错误
    
        begin
    
            print     'waring: skipping CREATE AS table 已经存在'
    
            
    
            --执行刚才的存储过程
    
            
    
            exec  dbo.uspLogError @ErrorLogID=@MyOutputParameter output;  --执行,插入error表
    
            print '发生一个错误。错误id'+cast(@MyOutputParameter as nvarchar);
    
        end
    
        
    
        else
    
           raiserror('something not good happend this time around',16,1)
    
    end catch
    

    2.游标代码

    本代码声明游标为global变量,在存储过程声明了游标,打开游标,但是唯独没close(关闭游标) 和 deallocate(清除游标分配到的内存)

    游标各中关键字使用 gloal/local;   static/dynmic/keyset/fast_forward

    static:不能感知原始表中数据的变化;存放在tempdb中

    dynmic:能感知;但是占用大量性能

    keyset:原始表必须有唯一索引,关键索引存在于tempdb中,能感知 删除,修改,不能感知新增的。

    use AdventureWorks
    
    go
    
    create proc  spCursorScope2
    
    AS
    
    
    
    declare @Counter  int;
    
    declare @OrderId  int;
    
    declare @CustomerId int
    
    
    
    declare CursorTest  cursor
    
    Global--默认,即使不填。   Glbal/local
    
    --<static,dynamic,keySet,Fast_forward>
    
    For
    
    	select SalesOrderId,CustomerID 
    
    	from Sales.SalesOrderHeader
    
    
    
    select @Counter=1;
    
    
    
    open  CursorTest
    
    fetch next from CursorTest into @OrderId,@CustomerId
    
    print 'Row '+cast(@Counter as nvarchar)+' has a SalesOrderId of '+convert(nvarchar,@OrderId)+' and a CustomerId of '+cast(@CustomerId as nvarchar)
    
    
    
    while(@@FETCH_STATUS=0) AND (@Counter<5)
    
    begin
    
    		select @Counter=@Counter+1;
    
    		fetch next from CursorTest into @OrderId,@CustomerId
    
    		print 'Row '+cast(@Counter as nvarchar)+' has a SalesOrderId of '+convert(nvarchar,@OrderId)+' and a CustomerId of '+cast(@CustomerId as nvarchar)
    
    
    
    end
    
    
    
    
    
    --上面的存储过程没有 close cursor ,和销毁 deallocate cursor
    
    
    
    exec spCursorScope2
    
    
    
    
    
    
    
    --重新声明几个变量,因为上面只有游标变量CursorTest 是全局的,其他的在存储过程外都要重新声明
    
    --一旦执行存储过程,则游标就执行了,而且没关闭之前一直在内存中。则存储过程后面的语句可以继续使用上面的游标
    
    exec spCursorScope
    
    declare @OrderId   int
    
    declare @CustomerId int
    
    declare @Counter int
    
    
    
    set @Counter=6
    
    
    
    while (@@FETCH_STATUS=0) AND (@Counter<=10)
    
    begin
    
    		fetch next from CursorTest into @OrderId,@CustomerId
    
    		print 'Row '+cast(@Counter as nvarchar)+' has a SalesOrderId of '+convert(nvarchar,@OrderId)+' and a CustomerId of '+cast(@CustomerId as nvarchar)
    
    		set @Counter=@Counter+1
    
    end
    
    
    
    
    
    close CursorTest
    
    deallocate CursorTest






    3.事务 (tran)

    Begin tran mytran; (名字可无)
    commit tran xx;
    rollback tran xx;
    save tran xx; //将此出标记为回滚点。 rollback tran 回滚点名字;就会回滚到回滚点和回滚方法之间,其他地方不会回滚的。

    例:

    Begin tran mytran;
      declare @i int
      set @i=0

    insert into students (name,sex) values ('小明',0)
    save tran xiaoming;
     insert into students (name,sex) values ('小龙',0)
     save tran xiaolong;


    rollback xiaoming; //回滚到xiaoming 回滚点

    commit tran mytran; //此时数据库里只有小明,没有小龙的数据。

    昂首阔步,不留一点遗憾
  • 相关阅读:
    Qt/Qml 电子书阅读器
    Qt/Qml 翻页特效
    vue如何引入本地js(不被打包编译的js)文件
    CSS3解决移动端手指点击或滑动屏幕时出现的浅蓝色背景框
    vue移动端touch插件
    vue组件间通信六种方式(完整版)
    Vue 过渡实现轮播图
    vue中遇到的坑 --- 变化检测问题(数组相关)
    Vue判断设备是移动端还是pc端
    vue项目如何监听窗口变化,达到页面自适应?
  • 原文地址:https://www.cnblogs.com/StudyLife/p/3155846.html
Copyright © 2020-2023  润新知