繁体   English   中英

SQL Server事务处理

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM