存在一個細微的差異,如下所示。
首次設置如下:
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
proc沒有。這是因爲一旦發生錯誤,控制就跳轉到CATCH
。
注意:pTMP2
的行爲受XACT_ABORT
設置的影響。
結論
使用TRY..CATCH
所證實的好處取決於你如何管理自己的事務邊界。
- 如果您回滾任何錯誤,則更改將被撤消。但是這並不能消除附加處理等副作用。注意:如果不同的會話使用
WITH(NOLOCK)
同時查詢TMP
,它甚至可能會觀察到臨時更改。
- 但是,如果您不打算回滾事務,則可能會發現該技術對於防止應用某些數據更改(儘管存在較早的錯誤)非常重要。
我能想到的唯一區別是,行號信息和錯誤號碼信息會更準確,因爲沒有`CATCH`拋出一個新的異常,所以它實際上似乎減去了值,據我所知。 .. – 2011-02-14 14:44:41
我總是喜歡在前端有一個自定義的錯誤消息,而不是sql生成的錯誤消息。這種方式會給你你理解和提到的邏輯和技術錯誤。 – Chris 2011-02-14 15:08:48