TRY...CATCH使用范例
BEGIN TRY //邏輯語句塊 END TRY
BEGIN CATCH //Catch異常處理塊 SET @msg = ERROR_MESSAGE(); PRINT @msg; END CATCH;
使用 TRY...CATCH 構造時,請遵循下列規則和建議:
-
每個 TRY...CATCH 構造都必須位於一個批處理、存儲過程或觸發器中。例如,不能將 TRY 塊放置在一個批處理中而將關聯的 CATCH 塊放置在另一個批處理中。
-
CATCH 塊必須緊跟 TRY 塊。
-
TRY…CATCH 構造可以是嵌套式的。這意味着可以將 TRY…CATCH 構造放置在其他 TRY 塊和 CATCH 塊內。當嵌套的 TRY 塊中出現錯誤時,程序控制將傳遞到與嵌套的 TRY 塊關聯的 CATCH 塊。
-
若要處理給定的 CATCH 塊中出現的錯誤,請在指定的 CATCH 塊中編寫 TRY...CATCH 塊。
-
TRY...CATCH 塊不處理導致數據庫引擎關閉連接的嚴重性為 20 或更高的錯誤。但是,只要連接不關閉,TRY...CATCH 就會處理嚴重性為 20 或更高的錯誤。
-
嚴重性為 10 或更低的錯誤被視為警告或信息性消息,TRY...CATCH 塊不處理此類錯誤。
-
即使批處理位於 TRY...CATCH 構造的作用域內,關注消息仍將終止該批處理。分布式事務失敗時,Microsoft 分布式事務處理協調器 (MS DTC) 將發送關注消息。MS DTC 用於管理分布式事務。
錯誤函數詳解
TRY...CATCH 使用下列錯誤函數來捕獲錯誤信息:
-
ERROR_NUMBER() 返回錯誤號。
-
ERROR_MESSAGE() 返回錯誤消息的完整文本。此文本包括為任何可替換參數(如長度、對象名或時間)提供的值。
-
ERROR_SEVERITY() 返回錯誤嚴重性。
-
ERROR_STATE() 返回錯誤狀態號。
-
ERROR_LINE() 返回導致錯誤的例程中的行號。
-
ERROR_PROCEDURE() 返回出現錯誤的存儲過程或觸發器的名稱。
可以使用這些函數從 TRY...CATCH 構造的 CATCH 塊的作用域中的任何位置檢索錯誤信息。如果在 CATCH 塊的作用域之外調用錯誤函數,錯誤函數將返回 NULL。在 CATCH 塊中執行存儲過程時,可以在存儲過程中引用錯誤函數並將其用於檢索錯誤信息。如果這樣做,則不必在每個 CATCH 塊中重復錯誤處理代碼。在下面的代碼示例中,TRY 塊中的 SELECT 語句將生成一個被零除錯誤。此錯誤將由 CATCH 塊處理,它將使用存儲過程返回錯誤信息。
BEGIN TRY -- Generate divide-by-zero error. SELECT 1/0; END TRY BEGIN CATCH -- Execute the error retrieval routine. EXECUTE usp_GetErrorInfo; END CATCH; GO
編譯錯誤和語句級重新編譯錯誤
對於與 TRY...CATCH 構造在同一執行級別發生的錯誤,TRY...CATCH 將不處理以下兩類錯誤:
-
編譯錯誤,例如阻止批處理執行的語法錯誤。
-
語句級重新編譯過程中出現的錯誤,例如由於名稱解析延遲而造成在編譯后出現對象名解析錯誤。
當包含 TRY...CATCH 構造的批處理、存儲過程或觸發器生成其中一種錯誤時,TRY...CATCH 構造將不處理這些錯誤。這些錯誤將返回到調用生成錯誤的例程的應用程序或批處理。例如,下面的代碼示例顯示導致語法錯誤的 SELECT 語句。如果在 SQL Server Management Studio 查詢編輯器中執行此代碼,則由於批處理無法編譯,執行將不啟動。錯誤將返回到查詢編輯器,將不會由 TRY...CATCH 捕獲。
USE Wot_Inventory; GO BEGIN TRY -- This PRINT statement will not run because the batch -- does not begin execution. PRINT N'Starting execution'; -- This SELECT statement contains a syntax error that -- stops the batch from compiling successfully. SELECT ** FROM Wot_Inventory.dbo.Invoice END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage; END CATCH; GO
與上述示例中的語法錯誤不同,語句級重新編譯過程中發生的錯誤不會阻礙批處理進行編譯,但是一旦語句重新編譯失敗,它會立即終止批處理。例如,如果批處理含有兩條語句並且第二條語句引用的表不存在,則延遲的名稱解析會使該批處理成功進行編譯並開始執行(無需將缺少的表綁定到查詢計划),直到重新編譯該語句為止。批處理到達引用缺失表的語句時將停止運行,並返回一個錯誤。在發生錯誤的執行級別,TRY...CATCH 構造將不處理此類錯誤。
有關詳細信息,請參閱處理數據庫引擎錯誤中的“在 Transact-SQL 中使用 TRY...CATCH”一節。
PS:歡迎掃描下方二維碼或點擊鏈接,加入QQ群