整容说文库 > 程序代码 > 教育资讯

循环能不能用事务???

来源:学生作业帮助网 编辑:整容说文库 时间:2019/05/27 06:06:54 程序代码
循环能不能用事务???程序代码
FETCH NEXT FROM Cur INTO @DANo,@UpdateTime,@LogTime,@DataType,@DAType,@DAYear,@DAMonth,@DADay,@DAHour,@CollegeNo,@CampusNo,@BuildingNo,@BuildingType,@SumQty,@EType,@EIndex,
@ESubitem,@ESubitem1,@ESubitem2,@Unit,@Lable,@Note

WHILE @@fetch_status=0 
BEGIN 

--print @BuildingType

--开始事务
BEGIN TRANSACTION
    SAVE TRANSACTION sp_Campus_TRANS

--提交事务
LABCOMMIT:
IF (@@error = 0)
BEGIN
COMMIT TRANSACTION
SET @Output=0
RETURN(0)
END

--以下回滚事务
LABROLLBACK:
BEGIN
      --插入报警信息
set @WarningMessage='学校数据:'+@CollegeNo+',编号:'+@DANo+',事务提交失败'
    insert  into  T_WarningMessage (DANo,DATime,CollegeNo,WarningType,Info)  values  (@DANo,@UpdateTime,@CollegeNo,'',@WarningMessage)

ROLLBACK TRANSACTION sp_Campus_TRANS
commit transaction
SET @Output=-1
RETURN @@error
END

[color=#008000]问题:
        这里用了一个游标循环取出来的数据,在循环中使用了一个事务。  发现事务处理完第一条数据,提交后,循环就终止了。 永远只会处理一条数据。  Why???   为什么会这样???  
 

[/color]

--填充游标变量
FETCH NEXT FROM Cur INTO @DANo,@UpdateTime,@LogTime,@DataType,@DAType,@DAYear,@DAMonth,@DADay,@DAHour,@CollegeNo,@CampusNo,@BuildingNo,@BuildingType,@SumQty,@EType,@EIndex,
@ESubitem,@ESubitem1,@ESubitem2,@Unit,@Lable,@Note
事务必须使用在 循环的外面吗???
没有这规定
楼主报什么错啊?贴出来看一下
应该是写法的问题

你的 while 内部,还应该有一个 FETCH NEXT FROM Cur INTO  
大概如下

FETCH NEXT FROM Cur INTO 
while @@fetch_status = 0 
begin
-- to do 

FETCH NEXT FROM Cur INTO   -- 这个不能丢了,不然就是永远第一个值 。
end -- end while 

建议事务放到游标外面。
万一游标出错呢?怎么办
能用,要善用事务
要用goto 配合循环
循环到出错数据时,是退出还是继续执行
RETURN--去掉
在游标里用了没有循环,用goto跳过
WHILE @@fetch_status=0 
BEGIN 

--print @BuildingType

--开始事务
BEGIN TRANSACTION
    SAVE TRANSACTION sp_Campus_TRANS

--提交事务
LABCOMMIT:
IF (@@error = 0)
BEGIN
COMMIT TRANSACTION
SET @Output=0
GOTO success
END

--以下回滚事务
LABROLLBACK:
BEGIN
      --插入报警信息
set @WarningMessage='学校数据:'+@CollegeNo+',编号:'+@DANo+',事务提交失败'
    insert  into  T_WarningMessage (DANo,DATime,CollegeNo,WarningType,Info)  values  (@DANo,@UpdateTime,@CollegeNo,'',@WarningMessage)

ROLLBACK TRANSACTION sp_Campus_TRANS

success:
commit TRANSACTION

SET @Output=-1
END
引用 4 楼 wmxcn2000 的回复:
你的 while 内部,还应该有一个 FETCH NEXT FROM Cur INTO  
大概如下

FETCH NEXT FROM Cur INTO 
while @@fetch_status = 0 
begin
-- to do 

FETCH NEXT FROM Cur INTO   -- 这个不能丢了,不然就是永远第一个值 。
end -- end while 



这个有的,在最下面。
引用 8 楼 roy_88 的回复:
WHILE @@fetch_status=0 
BEGIN 

--print @BuildingType

--开始事务
BEGIN TRANSACTION
    SAVE TRANSACTION sp_Campus_TRANS

--提交事务
LABCOMMIT:
IF (@@error = 0)
BEGIN
COMMIT TRANSACTION
SET @Output=0
GOTO success
END

--以下回滚事务
LABROLLBACK:
BEGIN
      --插入报警信息
set @WarningMessage='学校数据:'+@CollegeNo+',编号:'+@DANo+',事务提交失败'
    insert  into  T_WarningMessage (DANo,DATime,CollegeNo,WarningType,Info)  values  (@DANo,@UpdateTime,@CollegeNo,'',@WarningMessage)

ROLLBACK TRANSACTION sp_Campus_TRANS

success:
commit TRANSACTION

SET @Output=-1
END



WHILE @@fetch_status=0 
BEGIN 
 
--print @BuildingType
 
--开始事务
BEGIN TRANSACTION
    SAVE TRANSACTION sp_Campus_TRANS
 
--提交事务
LABCOMMIT:
IF (@@error = 0)
BEGIN
    COMMIT TRANSACTION   --第一次提交事务

    SET @Output=0
    GOTO success
END
 
--以下回滚事务
LABROLLBACK:
BEGIN
      --插入报警信息
set @WarningMessage='学校数据:'+@CollegeNo+',编号:'+@DANo+',事务提交失败'
    insert  into  T_WarningMessage (DANo,DATime,CollegeNo,WarningType,Info)  values  (@DANo,@UpdateTime,@CollegeNo,'',@WarningMessage)
 
ROLLBACK TRANSACTION sp_Campus_TRANS
 
success:
    commit TRANSACTION     --第二次提交事务

问题:这里事务提交了两次啊???
  

 
    SET @Output=-1
END
引用 10 楼 starrycheng 的回复:
问题:这里事务提交了两次啊???
  [/b][/color]
 
    SET @Output=-1
END


看你自己要什么效果,最外层有事务时才需要保存事务点,提交第2层事务再提交最外层事务,用save时首先要知道最外层有没有事务
IF @@TRANCOUNT>0 加判断
WHILE @@fetch_status=0 
BEGIN 
 
--print @BuildingType
 
--开始事务
BEGIN TRANSACTION
    SAVE TRANSACTION sp_Campus_TRANS
 
--提交事务
LABCOMMIT:
IF (@@error = 0)
BEGIN
    COMMIT TRANSACTION
    SET @Output=0
    GOTO success
END
 
--以下回滚事务
LABROLLBACK:
BEGIN
      --插入报警信息
set @WarningMessage='学校数据:'+@CollegeNo+',编号:'+@DANo+',事务提交失败'
    insert  into  T_WarningMessage (DANo,DATime,CollegeNo,WarningType,Info)  values  (@DANo,@UpdateTime,@CollegeNo,'',@WarningMessage)
 
ROLLBACK TRANSACTION sp_Campus_TRANS
 
success:
IF @@TRANCOUNT>0
    commit TRANSACTION
 
    SET @Output=-1
END
引用 12 楼 roy_88 的回复:
IF @@TRANCOUNT>0 加判断
WHILE @@fetch_status=0 
BEGIN 
 
--print @BuildingType
 
--开始事务
BEGIN TRANSACTION
    SAVE TRANSACTION sp_Campus_TRANS
 
--提交事务
LABCOMMIT:
IF (@@error = 0)
BEGIN
    COMMIT TRANSACTION
    SET @Output=0
    GOTO success
END
 
--以下回滚事务
LABROLLBACK:
BEGIN
      --插入报警信息
set @WarningMessage='学校数据:'+@CollegeNo+',编号:'+@DANo+',事务提交失败'
    insert  into  T_WarningMessage (DANo,DATime,CollegeNo,WarningType,Info)  values  (@DANo,@UpdateTime,@CollegeNo,'',@WarningMessage)
 
ROLLBACK TRANSACTION sp_Campus_TRANS
 
success:
IF @@TRANCOUNT>0
    commit TRANSACTION
 
    SET @Output=-1
END


大师,还有一个问题。

这样的25000行数据的循环处理,是把事务写在循环里面效率高,还是写在循环外面效率高啊。


引用 13 楼 starrycheng 的回复:
Quote: 引用 12 楼 roy_88 的回复:

IF @@TRANCOUNT>0 加判断
WHILE @@fetch_status=0 
BEGIN 
 
--print @BuildingType
 
--开始事务
BEGIN TRANSACTION
    SAVE TRANSACTION sp_Campus_TRANS
 
--提交事务
LABCOMMIT:
IF (@@error = 0)
BEGIN
    COMMIT TRANSACTION
    SET @Output=0
    GOTO success
END
 
--以下回滚事务
LABROLLBACK:
BEGIN
      --插入报警信息
set @WarningMessage='学校数据:'+@CollegeNo+',编号:'+@DANo+',事务提交失败'
    insert  into  T_WarningMessage (DANo,DATime,CollegeNo,WarningType,Info)  values  (@DANo,@UpdateTime,@CollegeNo,'',@WarningMessage)
 
ROLLBACK TRANSACTION sp_Campus_TRANS
 
success:
IF @@TRANCOUNT>0
    commit TRANSACTION
 
    SET @Output=-1
END


大师,还有一个问题。

这样的25000行数据的循环处理,是把事务写在循环里面效率高,还是写在循环外面效率高啊。



效率在于语句而不在于事务,事务影响可以忽略不计。
写在外面,出错时回滚所有操作,写在里面只回滚出错操作。

程序代码