浅谈游标与事物与错误消息机制

一、游标概念: 将某一结果集作为一个集合处理,且每次处理数据集的一行或一行的某些字段。
     建立游标结构如下:
   1. 定义游标,将游标与Transact-SQL语句的结果集相关联。
      Declare @bookid int, @bname varchar(50),@bindex int
      Declare book_cursor  cursor for
            Select bookid,bookname,bookIndex from Bas_bookList
    
   2.  执行Transact-SQL语句数据集填充游标即打开游标
Open book_cursor
 
   3.  从游标中检索到第一行,并提取第一行或第一行的某些字段。
       Fetch  next  from book_cursor  into @bookid,@bname,@bindex
 
   4.  根据需要对当前行进行操作
   @@Fetch_status包括三种状态 0,-1,-2。以此来判断游标执行是否正确。
    0则游标执行正确,-1 游标中出现错误,-2 找到空行
        While @@fetch_status=0
        Begin
           Delete update insert 等等
Fetch next  from book_cursor  into @bookid,@bname,@bindex  选取下一行数据
        End
 
  4.  关闭游标
    Close book_cursor
        Deallocate book_cursor
 
 
说明: 客户端游标,被odbc所支持,在使用时会有一些限制,只能使用只进和静态游标,它是把结果缓存到客户端,所有游标的操作都由客户端高速缓存下来。并不在服务器端执行,一般情况下都不这样使用, 只是对一些服务端不支持的Transact-sql和批处理才使用。
这小段只是我对客户端游标的理解,仅作参考。
 
二、事物,用起来很简单这里就不在详细介绍了。
 
1. 在存储过程中使用事物
 
     语句结构:
     事务起始点: Begin transaction 
     提交事物,完成自事物起始点开始的数据操作变化,释放事务所占用的资源:Commit TranSaction
     如果事务出现错误,回滚:Rollback
 
在事务起始点,begin transaction  tran1 使@@TRANCOUNT 按 1 递增
执行事务,commit ttansaction tran1    使@@TRANCOUNT 按1 递减,直到减少到0
回滚是到事务的起点或事务的某个保存点也就是定义点。
 
2. 在C#程序中也可以使用事物
   Using(System.Data.SqlClient.SqlConnection conn=new System.Data.SqlClient.SqlConnection(“数据库连接字符串”))
{
conn.open();
using (System.Data.SqlClient.SqlTransaction trans=conn.BeginTransaction())
{
    Try
{
 sql语句 ;
   Trans.Commit();
}
Catch
{
   Trans.Rollback();
}
}
}
三、Transact-SQL实现类似于C#语言中的异常处理。Transact-SQL语句组可以包含在TRY块中,如果TRY块内部发生错误,则会将事件处理转到Catch块中。
 
   语句结构
      BEGIN TRY
          Transact-SQL语句
      END TRY
      BEGIN CATCH
          错误处理机制
      END CATCH
       
其实以上讲述的基础知识。刚开始从事开发工作就知道明白,会用了。
此文只是系统地总结一下。供大家参考。算不上精辟。
 
我在实际的应用中发现一个问题,对于一个复杂的存储过程,把上面三种用法综合到一起,会提高不少的执行效率。一是为了找到错误点,回滚事物,把try和 transaction组合到一起,如果大量数据要处理,可能会用到游标,有时候在想,事物当执行commit的时候才会永久地处理数据,是不是在用游标的时候也这样,把游标写到事物里,把所有的游标都执行完毕,再进行事物处理,如果异常则回滚。试了一下,果然快很多。而且在Transact-Sql里同一存储过程定义的变量,在整个运行周期都是有效的,这就很好将整个构想实现了。例如:
 
   SET NOCOUNT ON;
          BEGIN TRY
         
           BEGIN TRANSACTION    tran1
          
                  DECLARE @proarageid BIGINT,@procomid BIGINT,@proagentid BIGINT,@progropid BIGINT
                
                 ---语句
           
 DECLARE acursor CURSOR
FOR SELECT id,provicename,cityname FROM Ass_ArrearageTemporary
                 OPEN acursor
                 FETCH NEXT FROM acursor INTO @proarageid,@procomid,@proagentid                 WHILE @@FETCH_STATUS = 0
                 BEGIN
                    ---语句
                         
                   FETCH NEXT FROM acursor INTO @proarageid,@procomid,@proagentid
                 END
                
                 COMMIT TRANSACTION tran1
                 CLOSE acursor
                 DEALLOCATE acursor
     END TRY
    begin CATCH
           IF @@TRANCOUNT > 0
        BEGIN
          CLOSE acursor
          DEALLOCATE acursor
          ROLLBACK  TRANSACTION tran1
          return
       END
    END CATCH

虽不是含量很高,但也是笔者的心血。

你可能感兴趣的:(数据库,职场,游标,休闲)