2011-09-04 71 views
2

我运行以下存储过程和我收到的COMMIT事务请求有没有相应的BEGIN TRANSACTION错误SQL Server事务处理

我在这里错过了什么?

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 
+1

您是否试图缩小您的陈述的范围?这是很多可能会干扰的事情。我建议一次删除一些内容,直到你得到一个更小的样本。那么也许可以更容易地看到问题出现在哪里。 –

+2

我建议你阅读['GO'](http://msdn.microsoft.com/en-us/library/ms188037.aspx)及其用途。它不应该存在于存储过程中。 – Oded

+0

@Oded:同意。 OP没有检查spImportData的状态,他们会在哪里看到什么是错误的 – gbn

回答

4

我会尝试只有一个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 
+1

+1使用“@@ ERROR”对我来说也不好看。 –

7

我在这里错过了什么?

您可能有盈余而非赤字。您需要删除GO报表。

脚本唯一合理的解释是它全部打算成为spImportData存储过程定义的一部分。

这将结束在第一GO声明(使用客户端工具来界定批次),其余批次立即执行在自动提交事务没有明确BEGIN TRAN已运行。当达到COMMIT声明时,没有任何提交,因此错误。