[转载]游标与事物与错误消息机制 – 交流空间 – 博客园.
一、游标概念: 将某一结果集作为一个集合处理,且每次处理数据集的一行或一行的某些字段。
建立游标结构如下:
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
虽不是含量很高,但也是笔者的心血。