如果在一组嵌套事务的任意级别执行没有 transaction_name 参数的 ROLLBACK WORK 或 ROLLBACK TRANSACTION 语句,那么它将回滚所有嵌套事务,包括最外部事务。作如下修改再试试: begin tran tran1
exec @res= pro_code @code
if @res=1
commit tran tran1
else
rollback tran tran1
exec @res= pro_code @code
if @res=1
commit tran tran1
else
rollback tran tran1
当 CURSOR_CLOSE_ON_COMMIT 设置为 OFF 时,ROLLBACK 不影响任何打开的同步 STATIC 或 INSENSITIVE 游标,也不影响已完全填充的异步 STATIC 游标。将关闭但不释放任何其它类型的打开的游标。你可以改变你的游标类型或者将游标包含在事务中
我试过了你的如下方法,无效:
begin tran tran1
exec @res= pro_code @code
if @res=1
commit tran tran1
else
rollback tran tran1
---------------------------------
lh1979(rocket) :
当 CURSOR_CLOSE_ON_COMMIT 设置为 ON 时,ROLLBACK 关闭但不释放所有打开的游标。
你说的这点有错误,帮助中说是提交时是否关闭游标,所以应改成如下:
当 CURSOR_CLOSE_ON_COMMIT 设置为 ON 时,COMMIT 关闭但不释放所有打开的游标。注意:这个选项是在事务提交commit时游标是否关闭。数据库默认是OFF,也就是commit后游标不关闭。
和我说的问题不同,我是在commit时正常,也就是不关闭游标,但rollback后游标被关闭。
---------------------------------
我的问题题目写的很清楚,错误出在:事务回滚rollback后,游标被关闭。要找个方法使rollback后,游标不被关闭,这样程序才能继续执行。
SET CURSOR_CLOSE_ON_COMMIT
The SET CURSOR_CLOSE_ON_COMMIT statement sets all cursors on a connection to automatically close when a COMMIT TRANSACTION or a ROLLBACK TRANSACTION statement is issued.Syntax
SET CURSOR_CLOSE_ON_COMMIT { ON | OFF };Arguments
ON Specifies closing all cursors on a connection when a COMMIT TRANSACTION or a ROLLBACK TRANSACTION statement is issued.OFF (default)Specifies that the calling application is required to close each cursor on a connection when a COMMIT TRANSACTION or a ROLLBACK TRANSACTION statement is issued.Res
You can use the SET CURSOR_CLOSE_ON_COMMIT command for standard and browse cursors.
create table table1(code int)
insert table1 select 1
union all select 2
union all select 3create table table2(id int,name nvarchar(20))
insert table2 select 1,'aa'
union all select 1,'bb'
union all select 2,'cc'
union all select 3,'dd'
go--测试的存储过程
create proc pro_code
@code int
as
update table2 set name=name+'_更新' where id=@code
if @code=2
return 0
else
return 1
go--更新测试
--set CURSOR_CLOSE_ON_COMMIT on --如果设置为这个,则执行结果会报错
set CURSOR_CLOSE_ON_COMMIT off --默认值
declare cur1 cursor fast_forward for
select code from table1
declare @code varchar(9)
declare @res varchar(9)
open cur1
while 1=1
begin
fetch next from cur1 into @code
if @@fetch_status<>0 break
begin tran
exec @res= pro_code @code
if @res=1
commit tran
else
rollback tran
end
close cur1
deallocate cur1
set CURSOR_CLOSE_ON_COMMIT off
go--显示结果
select * from table2
go--删除测试
drop table table1,table2
drop proc pro_code
/*--测试结果id name
----------- --------------------
1 aa_更新
1 bb_更新
2 cc
3 dd_更新(所影响的行数为 4 行)
--*/
原来在sql7.0中执行报错以上错误。
而sql2000里执行是不报错的。 zjcxc(邹建)大侠,你一定是在sql2000环境测试的吧。而数据库参数CURSOR_CLOSE_ON_COMMIT 默认设置为 OFF 。
我的sql7.0和sql2000数据库也都是OFF,没有改动过。
所以问题不是出在这里!
正确解释:
当 CURSOR_CLOSE_ON_COMMIT 设置为 OFF 时,COMMIT或ROLLBACK 关闭但不释放所有打开的游标。
我的存储过程和你测试用的几乎一样,只是简单的UPDATE,未使用事务。create proc pro_code
@code int
as
update table2 set name=name+'_更新' where id=@code
if @code=2
return 0
else
return 1
go
你认识有sql7环境的高手吗?帮忙测试解决一下吧!
这个问题有点郁闷!
我工作环境是sql7的数据库,调试程序的sql2000。
所以我必须在sql7中运行这个程序。
偏偏这个问题就是在sql7中才报错!对了,还有我的sql7是winnt4.0下的7.00.623。没装任何补丁!
也希望有哪个高手能帮忙解决此问题!多谢!
CURSOR_CLOSE_ON_COMMIT当设置为 ON 时,在提交事务时,所有打开的游标都将自动关闭。默认情况下,此设置为 OFF,并且游标仍然在各事务边界间保持打开状态,仅当连接关闭或被显式关闭时,才会关闭游标。连接级设置(使用 SET 语句设置)替代 CURSOR_CLOSE_ON_COMMIT 的默认数据库设置。默认情况下,当连接到 SQL Server 时,ODBC 和 OLE DB 客户端发出连接级 SET 语句,以将会话的 CURSOR_CLOSE_ON_COMMIT 设置为 OFF。
老兄你写的是什么意思啊?
我之前情况都说明了,我数据库CURSOR_CLOSE_ON_COMMIT 是默认设置OFF
问题不在此。而且我说的问题,相同的程序在sql2000中执行正常,但在sql7中执行报错。我用的是正版sql7,可惜一年的免费服务已经过期了,向微软问任何问题都要另付费!-_-|||
不过我想是否可以用这样的折冲方法。
在你在检测到错误时,就不要去关闭游标了。因为你都知道,游标已经管了。
只是在提交了事务后,才去关闭游标。