SQL Server中的事务和@@Error函数。

问题描述 投票:0回答:1

我只是想确认一下,我放的那个地方是否是 @@Error 和BeginCommit tran是正确的吗?

我不知道我是否应该将你的 Begin Tran 在...上 DELETE 语句代替?而且是否 @@ERROR 有意义吗?

谢谢!我只是想检查一下我放@@Error和BeginCommit tran的地方是否正确?

CREATE PROCEDURE spDeleteAnInactiveEmployee
    @TrainerID int,
    @EActive char (1)
AS
    BEGIN TRY
    BEGIN TRAN

        IF (SELECT COUNT(*) FROM EmployeeDetails ed 
            WHERE TrainerID = @TrainerID) = 0
          RAISERROR ('Trainer details were not deleted. Trainer ID does not exist.', 16, 1)

        IF EXISTS (SELECT * FROM EmployeeDetails ed 
                   WHERE TrainerID = @TrainerID AND EActive = 'Y')
            RAISERROR ('Trainer details were not deleted. Trainer is still active.', 16, 1)

        DELETE FROM [EmployeeDetails]    
        WHERE TrainerID = @TrainerID AND EActive = 'N'

        IF @@ERROR = 0
            COMMIT TRAN

        BEGIN
            PRINT 'Employee ID' + CAST (@TrainerID AS VARCHAR) + ' was successfully deleted.'
        END
    END TRY
    BEGIN CATCH
        SELECT
            ERROR_NUMBER() AS ErrorNumber,
            ERROR_STATE() AS ErrorState,
            ERROR_SEVERITY() AS ErrorSeverity,
            ERROR_PROCEDURE() AS ErrorProcedure,
            ERROR_LINE() AS ErrorLine,
            ERROR_MESSAGE() AS ErrorMessage;

        IF (XACT_STATE()) = -1
        BEGIN  
            PRINT 'Transaction was not committed' 
            ROLLBACK TRANSACTION;  
        END;  

        IF (XACT_STATE()) = 1
        BEGIN 
            PRINT 'Transaction was committed'
            COMMIT TRANSACTION;
        END;
    END CATCH;
GO
sql-server error-handling transactions commit rollback
1个回答
1
投票

@@ERROR是不必要的,当你使用TRYCATCH。 在使用TRYCATCH之前,你必须在每条可能失败的语句后检查@@ERROR,并使用GOTO强制控制流到一个错误标签。

所以这应该是类似于

CREATE PROCEDURE spDeleteAnInactiveEmployee
    @TrainerID int,
    @EActive char (1)
AS
BEGIN
    SET XACT_ABORT ON;
    BEGIN TRY
        BEGIN TRAN

        IF (SELECT COUNT(*) FROM EmployeeDetails ed 
            WHERE TrainerID = @TrainerID) = 0
          RAISERROR ('Trainer details were not deleted. Trainer ID does not exist.', 16, 1)

        IF EXISTS (SELECT * FROM EmployeeDetails ed 
                   WHERE TrainerID = @TrainerID AND EActive = 'Y')
            RAISERROR ('Trainer details were not deleted. Trainer is still active.', 16, 1)

        DELETE FROM [EmployeeDetails]    
        WHERE TrainerID = @TrainerID AND EActive = 'N'

        COMMIT TRAN
        PRINT 'Employee ID' + CAST (@TrainerID AS VARCHAR) + ' was successfully deleted.'
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0 ROLLBACK; 
        THROW;
    END CATCH;
END
© www.soinside.com 2019 - 2024. All rights reserved.