SQL Server事务处理
我正在运行以下存储过程,并收到错误消息 提交事务请求没有相应的开始事务 我错过了什么SQL Server事务处理,sql,sql-server,transactions,Sql,Sql Server,Transactions,我正在运行以下存储过程,并收到错误消息 提交事务请求没有相应的开始事务 我错过了什么 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 INSE
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 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事务,以及一个对应的COMMIT事务或一个对应的ROLLBACK事务
我通常还会将此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
你有没有试着把你的陈述缩小一点?这是很多可能会干扰的东西。我建议一次去掉一些内容物,直到你得到一个更小的样本。然后,也许可以更容易地看到问题发生在哪里。我建议您阅读相关内容以及它的用途。它不应该存在于存储过程中。@Oded:agree。OP还没有检查spImportData的状态,在那里他们会看到什么是错误的我会尝试一次开始尝试。。。。。结束TRY并将所有实际代码放在这个TRY块中,并将任何错误处理放在begincatch块中。TRY块中的最后一条语句是COMMIT,在CATCH块中有一个ROLLBACK。。。。您的这种微错误处理,与checkign@@error变量混杂在一起,没有多大意义……顺便说一句:尝试为同一个表多次设置IDENTITY\u INSERT不会引发错误。只有在另一个表的IDENTITY_INSERT已启用时,才会出现错误。