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
THROWing it? Also whyCOMMITthe transaction on error? Generally you don't want toCOMMITon error.@@ERRORcheck in the code, only normal structured handling. I suggest 1) specifySET 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 simplifiedIF @@TRANCOUNT > 0 ROLLBACK; THROW;(assuming SQL 2012 or later) to rollback the tran and re-raise the original error.does the @@ERROR make any sense at all- no, because in atryblock,raiserrorwill immediately jump tocatch. Outside of atryblock it would carry on and reach your@@error.