Sql語法高級應用之六:如何在Sql語句中如何使用TRY...CATCH


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群

一群用代碼改變世界的

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM