问一个带事务的存储过程模板???

sswp7 2014-07-09 03:10:42
ALTER procedure [dbo].[sp_TRANSACTION_Templater]
as

--带事务存储过程模板
begin
--开始事务
BEGIN TRANSACTION
SAVE TRANSACTION sp_Datacomputer_TRANS

问题一:这里的“SAVE TRANSACTION ”的作用是什么? 是设置一个回滚标记吗???

--事务内容


----------

--发生错误回滚事务
if (@@error <> 0)
begin
goto LABROLLBACK
end


问题二:SQL语句成功执行完了,这里并没有用“goto LABCOMMIT”手动提交事务。 SQL语句执行完后,事务会自动提交对吧???


--提交事务
LABCOMMIT:
if (@@error = 0)
begin
COMMIT TRANSACTION
return(0)
end
--以下回滚事务
LABROLLBACK:
begin
ROLLBACK TRANSACTION sp_Datacomputer_TRANS
return @@error
end

问题三:在“BEGIN TRANSACTION”外面加一个判断,和在它里面加个判断应该都没有问题吧???



end




...全文
144 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
starrycheng 2014-07-14
  • 打赏
  • 举报
回复
引用 14 楼 DBA_Huangzj 的回复:
为什么要两个号轮着来?算了,完事记得结贴。。
恩。记得记得。不结贴,发不了新帖子。
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
为什么要两个号轮着来?算了,完事记得结贴。。
starrycheng 2014-07-09
  • 打赏
  • 举报
回复
引用 10 楼 DBA_Huangzj 的回复:
--提交事务 LABCOMMIT: IF ( @@error = 0 ) BEGIN COMMIT TRANSACTION RETURN(0) END --以下回滚事务 LABROLLBACK: BEGIN ROLLBACK TRANSACTION sp_Datacomputer_TRANS RETURN @@error END 你可以看它的顺序,commit在前,这个存储过程是顺序执行的,也就是说不发升错误的话一定会执行到commit这个,执行完return跳出,就不会执行rollback了,只有在发生错误时才跳过commit这段逻辑进入rollback这里,所以不需要goto,如果你反过来这样写: --以下回滚事务 LABROLLBACK: BEGIN ROLLBACK TRANSACTION sp_Datacomputer_TRANS RETURN @@error END --提交事务 LABCOMMIT: IF ( @@error = 0 ) BEGIN COMMIT TRANSACTION RETURN(0) END 那么就有问题了,你可以找个测试环境测测,应该全部rollback
嗯,谢谢大师终于明白了。
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
这也是我说的不要用goto,会混乱思维的
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
别两个号乱流问好吧,切换用户你不累吗?
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
--提交事务 LABCOMMIT: IF ( @@error = 0 ) BEGIN COMMIT TRANSACTION RETURN(0) END --以下回滚事务 LABROLLBACK: BEGIN ROLLBACK TRANSACTION sp_Datacomputer_TRANS RETURN @@error END 你可以看它的顺序,commit在前,这个存储过程是顺序执行的,也就是说不发升错误的话一定会执行到commit这个,执行完return跳出,就不会执行rollback了,只有在发生错误时才跳过commit这段逻辑进入rollback这里,所以不需要goto,如果你反过来这样写: --以下回滚事务 LABROLLBACK: BEGIN ROLLBACK TRANSACTION sp_Datacomputer_TRANS RETURN @@error END --提交事务 LABCOMMIT: IF ( @@error = 0 ) BEGIN COMMIT TRANSACTION RETURN(0) END 那么就有问题了,你可以找个测试环境测测,应该全部rollback
starrycheng 2014-07-09
  • 打赏
  • 举报
回复
引用 8 楼 DBA_Huangzj 的回复:
这两部分已经符合了显式事务的操作,只是没格式化代码看漏了而已 -提交事务因为有了这部分,所以显式提交了 LABCOMMIT: if (@@error = 0) begin COMMIT TRANSACTION return(0) end --以下回滚事务 这部分是显式回滚 LABROLLBACK: begin ROLLBACK TRANSACTION sp_Datacomputer_TRANS return @@error end
不用“goto LABCOMMIT”这样就可以提交吗??? 没有用Goto, LABCOMMIT: if (@@error = 0) begin COMMIT TRANSACTION return(0) end 这部分代码也会被执行吗??? 并没有”Goto“到这里啊。
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
这两部分已经符合了显式事务的操作,只是没格式化代码看漏了而已 -提交事务因为有了这部分,所以显式提交了 LABCOMMIT: if (@@error = 0) begin COMMIT TRANSACTION return(0) end --以下回滚事务 这部分是显式回滚 LABROLLBACK: begin ROLLBACK TRANSACTION sp_Datacomputer_TRANS return @@error end
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
你这里有两个部分,一个是处理回滚,一个是处理提交,所以没问题。没有格式化的代码比较难看,看漏了,下面仅帮你格式化而已。
ALTER  PROCEDURE [dbo].[sp_DataComputer_WenYuanDatas]
    @DANo CHAR(32) ,--20110112182345207插入时间
    @DATime DATETIME ,--采集时间
    @LogTime DATETIME ,--更新时间
    @MeterType CHAR(4) ,--表具类型
    @MeterNo CHAR(20) ,--表具号码
    @Qty DECIMAL(18, 6) ,--数值
    @Unit CHAR(4) ,--单位
    @outputpar INT = 0 OUTPUT--输出返回值
AS --带事务存储过程模板


    BEGIN
--开始事务
        BEGIN TRANSACTION
        SAVE TRANSACTION sp_Datacomputer_TRANS

--事务内容,计算时日月数据.
    
        DECLARE @DAYear CHAR(4);
        DECLARE @DAMonth CHAR(2);
        DECLARE @DADay CHAR(2);
        DECLARE @DAHour CHAR(2);

        DECLARE @RowCnt_Year INT;
        DECLARE @RowCnt_Month INT;
        DECLARE @RowCnt_Day INT;
        DECLARE @RowCnt_Hour INT;

        SET @DAYear = SUBSTRING(LTRIM(RTRIM(CONVERT(VARCHAR(10), @DATime, 120))),
                                1, 4);
        SET @DAMonth = SUBSTRING(LTRIM(RTRIM(CONVERT(VARCHAR(10), @DATime, 120))),
                                 6, 2);
        SET @DADay = SUBSTRING(LTRIM(RTRIM(CONVERT(VARCHAR(10), @DATime, 120))),
                               9, 2);
        SET @DAHour = SUBSTRING(LTRIM(RTRIM(CONVERT(VARCHAR(10), @DATime, 114))),
                                1, 2);



        SET @RowCnt_Year = ( SELECT COUNT(*)
                             FROM   WenYuanEnergyDataSumByYear
                             WHERE  MeterNo = @MeterNo
                                    AND MeterType = @MeterType
                                    AND DAYear = @DAYear
                           );

        IF ISNULL(@RowCnt_Year, 0) = 0
            BEGIN
                SET @RowCnt_Year = 0;
            END


        IF @RowCnt_Year > 0
            BEGIN
                UPDATE  WenYuanEnergyDataSumByYear
                SET     SumQty = SumQty + @Qty
                WHERE   MeterNo = @MeterNo
                        AND MeterType = @MeterType
                        AND DAYear = @DAYear;
            END
        ELSE
            BEGIN
                INSERT  WenYuanEnergyDataSumByYear
                        ( MeterNo ,
                          MeterType ,
                          DAYear ,
                          SumQty ,
                          Unit
                        )
                        SELECT  @MeterNo ,
                                @MeterType ,
                                @DAYear ,
                                @Qty ,
                                @Unit;
            END
    
----------

--发生错误回滚事务
        IF ( @@error <> 0 )
            BEGIN
                GOTO LABROLLBACK
            END

--提交事务
        LABCOMMIT:
        IF ( @@error = 0 )
            BEGIN
                COMMIT TRANSACTION
                RETURN(0)
            END
--以下回滚事务
        LABROLLBACK:
        BEGIN
            ROLLBACK TRANSACTION sp_Datacomputer_TRANS
            RETURN @@error
        END

    END
starrycheng 2014-07-09
  • 打赏
  • 举报
回复
这里没有用““goto LABCOMMIT”手动提交事务”,数据一样完成了插入和更新,为什么???
sswp7 2014-07-09
  • 打赏
  • 举报
回复
引用 3 楼 DBA_Huangzj 的回复:
看了一下你这个模版,有点问题,应该直接判断是否有错并作出判断,而模版只有对--发生错误回滚事务的才操作
谢谢大师,但是,这个模板已经在使用了。 事务好像会自动提交的,数据已经插入和更新到表了。 USE [CloudDatasCenter] GO /****** Object: StoredProcedure [dbo].[sp_DataComputer_WenYuanDatas] Script Date: 07/09/2014 15:14:48 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER procedure [dbo].[sp_DataComputer_WenYuanDatas] @DANo Char(32),--20110112182345207插入时间 @DATime Datetime,--采集时间 @LogTime Datetime,--更新时间 @MeterType Char(4),--表具类型 @MeterNo Char(20),--表具号码 @Qty Decimal(18,6),--数值 @Unit Char(4),--单位 @outputpar int = 0 output--输出返回值 as --带事务存储过程模板 begin --开始事务 BEGIN TRANSACTION SAVE TRANSACTION sp_Datacomputer_TRANS --事务内容,计算时日月数据. Declare @DAYear Char(4); Declare @DAMonth Char(2); Declare @DADay Char(2); Declare @DAHour Char(2); Declare @RowCnt_Year Int; Declare @RowCnt_Month Int; Declare @RowCnt_Day Int; Declare @RowCnt_Hour Int; Set @DAYear = Substring(Ltrim(Rtrim(Convert(varchar(10),@DATime,120))),1,4); Set @DAMonth = Substring(Ltrim(Rtrim(Convert(varchar(10),@DATime,120))),6,2); Set @DADay = Substring(Ltrim(Rtrim(Convert(varchar(10),@DATime,120))),9,2); Set @DAHour = Substring(Ltrim(Rtrim(Convert(varchar(10),@DATime,114))),1,2); Set @RowCnt_Year = (Select Count(*) From WenYuanEnergyDataSumByYear Where MeterNo = @MeterNo And MeterType = @MeterType And DAYear = @DAYear); If IsNull(@RowCnt_Year,0) = 0 Begin Set @RowCnt_Year = 0; End If @RowCnt_Year > 0 Begin Update WenYuanEnergyDataSumByYear Set SumQty = SumQty + @Qty Where MeterNo = @MeterNo And MeterType = @MeterType And DAYear = @DAYear ; End Else Begin Insert WenYuanEnergyDataSumByYear(MeterNo,MeterType,DAYear,SumQty,Unit) Select @MeterNo,@MeterType,@DAYear,@Qty,@Unit; End ---------- --发生错误回滚事务 if (@@error <> 0) begin goto LABROLLBACK end --提交事务 LABCOMMIT: if (@@error = 0) begin COMMIT TRANSACTION return(0) end --以下回滚事务 LABROLLBACK: begin ROLLBACK TRANSACTION sp_Datacomputer_TRANS return @@error end end 这个存储过程中没有显示调用“COMMIT TRANSACTION”,数据一样插入和更新到指定表了。
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
GOTO在C/SQL里面都不建议使用,在很长的代码里面,goto会导致数据流的混乱,调试起来很麻烦
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
看了一下你这个模版,有点问题,应该直接判断是否有错并作出判断,而模版只有对--发生错误回滚事务的才操作
starrycheng 2014-07-09
  • 打赏
  • 举报
回复
用Goto语句,感觉比较好看啊,有错误就跳到回滚。 但有什么特别注意的地方吗???
發糞塗牆 2014-07-09
  • 打赏
  • 举报
回复
问题一:这里的“SAVE TRANSACTION ”的作用是什么? 是设置一个回滚标记吗??? 设置一个事务的保存点,可以用于回滚特定部分 问题二:SQL语句成功执行完了,这里并没有用“goto LABCOMMIT”手动提交事务。 SQL语句执行完后,事务会自动提交对吧??? 不会 用了begin tran,就要显式使用commit/rollback 问题三:在“BEGIN TRANSACTION”外面加一个判断,和在它里面加个判断应该都没有问题吧??? 当然有,在里面加算是事务里面的东西,在外面加就不算这个事务的东西,在回滚时有不同的结果

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧