2008-11-06 54 views

回答

2

此處適用的一般規則是儘可能將錯誤儘可能接近源。 SQL Server現在有「try ... catch ...」錯誤捕獲語法。所以使用它。額外代碼的一小部分開銷是微不足道的,如果在SP中有多個語句,則可以調整RAISERROR中的字符串以幫助本地化問題。

在界面中,捕獲SP錯誤事件並處理它,應用程序代碼中處理其他錯誤陷阱的方式應該不難。

這是存儲過程中最被忽視的「最佳實踐」之一,它比「常規」代碼更重要,因爲使用step = through調試器會更復雜。

一個有用的模式是在你的SP中處理它,就像你期望它在任何其他不透明的SDK庫中處理一樣。

0

我使用try/catch對庫或包括數據庫查詢在內的其他服務器生成調用的所有潛在錯誤。我主要是一個開發人員而不是DBA,所以我用我最熟練的語言來處理錯誤,而不是SQL。我相信每個程序員都會有所不同。在我的書中沒有處理錯誤是不好的。

0

我更喜歡這兩個 -

  • 存儲過程調用RAISEERROR,它表現爲在ADO.NET異常
  • 存儲過程返回錯誤代碼,如果一個存儲過程的調用另一個
一般

,我總是做一個try-catch

1

根據本article內部數據庫調用,這是一種「愚蠢的「例外 - 即如果SP發生錯誤,這意味着SP或數據本身出現問題。

我的建議是將錯誤捕獲到aps.net中,因爲您有更多的記錄錯誤的可能性以及爲了調查問題而傳遞給SP的所有參數。

+0

我認爲這種異常是外生的或致命的。例如,由於丟失數據,或者因爲網絡故障,sproc可能會失敗。但你的建議是正確的:始終在asp.net代碼中捕獲錯誤 – 2008-11-06 15:36:52

+0

連接關閉不是SP錯誤,而是調用代碼錯誤。 SP應該仔細構建,所以如果數據丟失,它不會引發異常。或者,另一方面,它可能是數據不一致的信號。無論如何,它需要修復。 – 2008-11-06 15:41:02

0

數據層中最可能的故障模式是錯誤的用戶輸入值,例如請求不存在的記錄。大多數其他錯誤都是由代碼損壞引起的,通常在測試時立即被捕獲。我喜歡捕獲數據庫錯誤,並且總是拋出一個自定義錯誤,提供關於請求數據和上下文的更多信息。然後這個錯誤會回調調用堆棧,如果這是一個用戶可糾正的錯誤,我可以提醒他們注意這個事實。否則當錯誤到達堆棧頂部時,應用程序的中央錯誤頁面處理程序將被調用。最糟糕的事情是要抓住一個錯誤,不要讓它回暖。返回代碼是過時的構造,除非與COM組件或外部系統交談。

0

理想情況下,您的Web應用程序不知道後端或數據訪問。所以它不應該處理與sql相關的錯誤 - 這些錯誤應該由數據訪問層處理。但是,Web應用程序需要通過向最終用戶提供友好的消息來優雅地處理失敗。

0

我會說這取決於你在存儲過程中所做的事情以及你想要對發生的某些錯誤做什麼。有時我會在sp中處理它,但有時我會讓它升到數據層代碼。請記住,有時您可能會錯過使用sql server 2005 try/catch時發生的錯誤,請參閱my post。而在代碼中(我的例子是C#),你可以訪問SqlErrorCollection對象中的所有錯誤。

只要確定你在存儲過程中的錯誤處理是經過深思熟慮的,任何不確定性都留給數據層代碼,你必須記錄下所有的東西。

0

答案是你需要兩個都做。一些錯誤實際上是從數據庫引擎下行觸發的。當然,它們的來源根據您連接數據庫的實際方式(OLBC,OLEDB等)而有所不同。你必須找到解決這些問題的方法。一些錯誤,例如死鎖錯誤也將在應用程序級別處理。

除了錯誤之外,接收和處理來自SQL Server數據庫引擎的消息也是一個好主意。這些與錯誤非常相似,可以爲應用程序提供大量有用的診斷信息。如果您使用的是System.Data.SQLClient,則需要創建一個SqlInfoMessageEventHandler委託,標識處理該事件的方法以偵聽SqlConnection類上的InfoMessage事件。您會發現諸如嚴重性和狀態的消息上下文信息作爲參數傳遞給回調函數,因爲從系統角度來看,這些消息就像錯誤一樣。 我希望這有助於!