问题一:这里的“SAVE TRANSACTION ”的作用是什么? 是设置一个回滚标记吗???
设置一个事务的保存点,可以用于回滚特定部分问题二:SQL语句成功执行完了,这里并没有用“goto LABCOMMIT”手动提交事务。 SQL语句执行完后,事务会自动提交对吧???
不会用了begin tran,就要显式使用commit/rollback
问题三:在“BEGIN TRANSACTION”外面加一个判断,和在它里面加个判断应该都没有问题吧???
当然有,在里面加算是事务里面的东西,在外面加就不算这个事务的东西,在回滚时有不同的结果
设置一个事务的保存点,可以用于回滚特定部分问题二:SQL语句成功执行完了,这里并没有用“goto LABCOMMIT”手动提交事务。 SQL语句执行完后,事务会自动提交对吧???
不会用了begin tran,就要显式使用commit/rollback
问题三:在“BEGIN TRANSACTION”外面加一个判断,和在它里面加个判断应该都没有问题吧???
当然有,在里面加算是事务里面的东西,在外面加就不算这个事务的东西,在回滚时有不同的结果
谢谢大师,但是,这个模板已经在使用了。 事务好像会自动提交的,数据已经插入和更新到表了。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
endend这个存储过程中没有显示调用“COMMIT TRANSACTION”,数据一样插入和更新到指定表了。
@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
-提交事务因为有了这部分,所以显式提交了
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“到这里啊。
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