SQL 服务器中的事务和@@Error 函数

Transactions and @@Error function in SQL Server

我只是想看看我放@@Error和Begin/Commit的地方是否正确?

我不确定我是否应该用 Begin Tran 代替 DELETE 语句? @@ERROR 有任何意义吗?

谢谢!

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
使用 TRY/CATCH 时,

@@ERROR 是不必要的。在 TRY/CATCH 之前,您必须在每个可能失败的语句之后检查 @@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