簡體   English   中英

SQL嘗試捕獲目的不清楚

[英]SQL Try catch purpose unclear

假設我想通知應用程序發生了什么/返回了SQL Server。 讓我們有以下代碼塊:

BEGIN TRY
    -- Generate divide-by-zero error.
    SELECT 1/0;
END TRY
BEGIN CATCH
     SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() as ErrorState,
        ERROR_PROCEDURE() as ErrorProcedure,
        ERROR_LINE() as ErrorLine,
        ERROR_MESSAGE() as ErrorMessage;
END CATCH;
GO

和讓我們有這個代碼塊:

SELECT 1/0;

我的問題是: 都返回零誤差除法 我不明白的是,為什么在兩種情況下都出現該錯誤時,為什么都應該用try catch子句包圍它? 在兩種情況下都會將此錯誤傳播到客戶端應用程序,這是不是真的?

是的,嘗試捕獲的唯一原因(如在普通代碼中一樣)是您是否可以“處理”錯誤,即,您可以更正錯誤並成功完成該程序要執行的任何功能,或者,如果需要在將錯誤返回給客戶端之前做一些處理(例如修改消息,或將其存儲在錯誤日志表中或向某人發送電子郵件等)。(盡管我更喜歡從DAL層進行這些操作)

但是,從技術上講,catch子句不會返回錯誤。 它只是返回帶有錯誤信息的結果集。 這是非常不同的,因為它不會在客戶端代碼中引起異常。 這就是為什么您的結論正確的原因,您應該只將原始錯誤直接傳播回客戶端代碼。

如您所寫,沒有錯誤將返回給客戶端。 與在普通代碼中一樣,如果您不處理(糾正)catch子句中的錯誤,則應始終在catch子句中將其重新拋出(在sql中,這意味着Raiserror函數)。 上面所做的事情通常是不好的,客戶端代碼可能具有或可能不具有正確處理與期望的完全不同的記錄集(帶有錯誤信息的一個記錄集)的任何功能。 某些調用(例如,插入更新或刪除)可能根本不期望或正在尋找返回的記錄集...而是,如果您希望或需要對過程中的錯誤進行處理,然后再將其返回給客戶端,請使用Raiserror()功能

BEGIN TRY 
    -- Generate divide-by-zero error. 
    SELECT 1/0; 
END TRY 
BEGIN CATCH 
     -- Other code to do logging, whatever ... 
     Raiserror(ERROR_MESSAGE(), ERROR_NUMBER(), ERROR_STATE() )
END CATCH; 

兩者都返回除以零的錯誤。

是的,但是使用不同的返回路徑。

不同之處在於,在第一個示例中,您正在預料該錯誤並以某種方式對其進行處理。 錯誤會作為常規結果進入應用程序-它不會通過錯誤處理機制傳播。 實際上,如果應用程序看起來不像結果的形狀那樣,則可能不知道發生了錯誤。

在第二種情況下,錯誤通常會通過錯誤報告機制(例如異常)傳播到您的應用程序。 這將中止操作。 影響有多大取決於應用程序的異常處理。 也許它將僅中止當前操作,否則整個應用程序可能會失敗,具體取決於應用程序的設計和對異常的容忍度。

您選擇對您的應用程序有意義的內容。 應用程序是否可以有意義地處理錯誤-如果是這樣,則傳播錯誤(第二個示例),或者最好在查詢中進行處理(第一個示例),通過返回默認結果(例如空行集)來“消除”錯誤。

當您在try部分中僅有的一個select時,Try Catch沒有那么有用。 但是,如果您的事務具有多個步驟,則catch塊將用於回滾所有步驟,並可能在日志中記錄有關導致問題的原因的詳細信息。 但是最重​​要的部分是回滾以確保數據完整性。

如果要在Try塊中創建動態SQl,則記錄失敗的動態SQl變量和傳入的任何參數也很有幫助。這可以幫助解決一些難以捉摸的問題,“我們不知道用戶實際上確實造成了問題”錯誤。

否,通過在TRY / CATCH塊中執行Select 1/0 / Select 1/0 ,select語句不返回任何內容,而catch塊中的select語句可以優雅地顯示錯誤詳細信息。 查詢成功完成-不會引發任何錯誤。

如果自行運行Select 1/0 ,查詢將無法成功完成-它會炸出錯誤。

在SQL中使用catch塊可以使您有機會在其中執行某些操作,而不僅僅是讓錯誤冒泡到應用程序中。

您看到錯誤詳細信息的唯一原因是因為您正在選擇它們。 如果Catch塊中沒有代碼,您將看不到任何錯誤信息。

使用第一種方法,您不會直接從SQL Server中獲取錯誤

第二種方法可能會停止執行其后的語句

所以最好先抓

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM