Существует небольшая разница, как показано ниже.
Сначала настройте следующее:
CREATE TABLE TMP
( ROW_ID int NOT NULL,
ALTER TABLE TMP ADD CONSTRAINT PK_TMP PRIMARY KEY CLUSTERED (ROW_ID)
)
GO
CREATE PROC pTMP1
AS
BEGIN TRY
INSERT INTO TMP VALUES(1)
INSERT INTO TMP VALUES(1)
INSERT INTO TMP VALUES(2)
END TRY
BEGIN CATCH
DECLARE @ErrMsg varchar(max)= ERROR_MESSAGE(),
@ErrSev int = ERROR_SEVERITY(),
@ErrState int = ERROR_STATE()
RAISERROR (@ErrMsg, @ErrSev, @ErrState)
END CATCH
GO
CREATE PROC pTMP2
AS
INSERT INTO TMP VALUES(1)
INSERT INTO TMP VALUES(1)
INSERT INTO TMP VALUES(2)
GO
Теперь выполните следующее:
SET NOCOUNT ON
DELETE TMP
exec pTMP1
SELECT * FROM TMP
DELETE TMP
exec pTMP2
SELECT * FROM TMP
SET NOCOUNT OFF
--Cleanup
DROP PROCEDURE pTMP1
DROP PROCEDURE pTMP2
DROP TABLE TMP
Вы должны получитьследующие результаты:
Msg 50000, Level 14, State 1, Procedure pTMP1, Line 12
Violation of PRIMARY KEY constraint 'PK_TMP'. Cannot insert duplicate key in object 'dbo.TMP'. The duplicate key value is (1).
ROW_ID
-----------
1
Msg 2627, Level 14, State 1, Procedure pTMP2, Line 4
Violation of PRIMARY KEY constraint 'PK_TMP'. Cannot insert duplicate key in object 'dbo.TMP'. The duplicate key value is (1).
The statement has been terminated.
ROW_ID
-----------
1
2
Обратите внимание, что версия TRY..CATCH
не выполнила третий оператор INSERT
, в то время как процедура pTMP2
выполнила.Это связано с тем, что управление переходит к CATCH
, как только возникает ошибка.
ПРИМЕЧАНИЕ. Параметр XACT_ABORT
влияет на поведение pTMP2
.
Заключение
Преимущество использования TRY..CATCH
, как продемонстрировано, зависит от того, как вы управляете границами транзакции.
- Если вы откатываетесь по любой ошибке, изменения будут отменены.Но это не устраняет побочные эффекты, такие как дополнительная обработка.ПРИМЕЧАНИЕ. Если другой сеанс одновременно запрашивает
TMP
с использованием WITH(NOLOCK)
, он может даже наблюдать временное изменение. - Однако, если вы не собираетесь откатывать транзакцию, вы можете найти методочень важно предотвратить применение определенных изменений данных, несмотря на более раннюю ошибку.