[英]SQL Server transaction handling
我正在运行以下存储过程,我收到错误
COMMIT TRANSACTION请求没有相应的BEGIN TRANSACTION。
我在这里想念的是什么?
CREATE PROCEDURE spImportData
AS
BEGIN TRANSACTION
BEGIN TRY
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType ON
END TRY
BEGIN CATCH
PRINT 'IDENTITY_INSERT IS ON'
END CATCH
GO
BEGIN TRY
INSERT INTO PINCDOCControlNew..tblActionType(ActionTypeID,ActionType,ActionTypeDescription)
SELECT ActionTypeID,ActionType,ActionTypeDescription
FROM PINCDOCControlOld..tblActionType
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType OFF
END TRY
BEGIN CATCH
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType OFF
EXECUTE usp_GetErrorInfo
END CATCH
BEGIN TRY
SET IDENTITY_INSERT PINCDOCControlNew..tblArea ON
END TRY
BEGIN CATCH
PRINT 'IDENTITY_INSERT IS ON'
END CATCH
GO
BEGIN TRY
INSERT INTO PINCDOCControlNew..tblArea(AreaID,AreaDescription,AreaNo)
SELECT AreaNo,AreaDescription,Area
FROM PINCDOCControlOld..tblArea
SET IDENTITY_INSERT PINCDOCControlNew..tblArea OFF
END TRY
BEGIN CATCH
SET IDENTITY_INSERT PINCDOCControlNew..tblArea OFF
EXECUTE usp_GetErrorInfo
END CATCH
IF @@ERROR <> 0
BEGIN
-- Rollback the transaction
ROLLBACK
-- Raise an error and return
RAISERROR ('Error in inserting.', 16, 1)
RETURN
END
COMMIT
我在这里失踪了什么?
你可能有盈余而不是赤字。 您需要删除GO
语句。
对脚本唯一合理的解释是它都是spImportData
存储过程定义的一部分。
这结束于第一个GO
语句(由客户端工具用于分隔批处理),其余批处理在自动提交事务中立即执行 ,因为没有运行明确的BEGIN TRAN
。 当达到COMMIT
语句时,没有任何提交因此错误。
我会尝试只有一个BEGIN TRY .... END TRY
块,在其中你有你想要执行的所有逻辑。 如果出现任何问题 - 在你的逻辑中的任何地方 - 你将被扔进BEGIN CATCH.... END CATCH
块。
在BEGIN TRY
之前启动事务,并将唯一的COMMIT
作为TRY
块中的最后一个语句 - 并在您的CATCH
块中进行回滚。
像这样的东西:
CREATE PROCEDURE dbo.spImportData
AS
BEGIN TRANSACTION
BEGIN TRY
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType ON
INSERT INTO
PINCDOCControlNew..tblActionType(ActionTypeID, ActionType, ActionTypeDescription)
SELECT
ActionTypeID, ActionType, ActionTypeDescription
FROM
PINCDOCControlOld..tblActionType
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType OFF
-- tblArea
SET IDENTITY_INSERT PINCDOCControlNew..tblArea ON
INSERT INTO
PINCDOCControlNew..tblArea(AreaID, AreaDescription, AreaNo)
SELECT
AreaNo, AreaDescription, Area
FROM
PINCDOCControlOld..tblArea
SET IDENTITY_INSERT PINCDOCControlNew..tblArea OFF
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType OFF
SET IDENTITY_INSERT PINCDOCControlNew..tblArea OFF
EXECUTE usp_GetErrorInfo
RAISERROR ('Error in inserting.', 16, 1)
END CATCH
使用这种方法,您只有一个 BEGIN TRANSACTION
,并且只有一个对应的COMMIT TRANSACTION
或一个对应的ROLLBACK TRANSACTION
我通常还将此SELECT
语句添加到我的CATCH
块以获取错误消息和出错的错误代码:
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.