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
我只是想看看我放@@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
@@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