0

I just want to check if the place where I put the @@Error and Begin/Commit tran is correct?

I am unsure if I should you the Begin Tran over the DELETE statement instead? And does the @@ERROR make any sense at all?

Thanks!

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
4
  • Why are you selecting the error here? Wouldn't you be better off THROWing it? Also why COMMIT the transaction on error? Generally you don't want to COMMIT on error. Commented Jun 3, 2020 at 12:38
  • I see no @@ERROR check in the code, only normal structured handling. I suggest 1) specify SET XACT_ABORT ON; at the beginning of the proc to ensure immediate rollback in the case of a query timeout and 2) change the catch block to the simplified IF @@TRANCOUNT > 0 ROLLBACK; THROW; (assuming SQL 2012 or later) to rollback the tran and re-raise the original error. Commented Jun 3, 2020 at 12:38
  • Sorry I meant to say @@Error rather than @@Rowcount. Commented Jun 3, 2020 at 13:18
  • 1
    does the @@ERROR make any sense at all - no, because in a try block, raiserror will immediately jump to catch. Outside of a try block it would carry on and reach your @@error. Commented Jun 3, 2020 at 15:59

1 Answer 1

1

@@ERROR is unnecessary when you use TRY/CATCH. Before TRY/CATCH you had to check @@ERROR after each statement that might fail and use GOTO to force control flow to an error label.

So this should be something like:

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.