top
Loading...
淺談如何處理數據層錯誤

開發人員在努力做到妥善地處理意外,這樣用戶就不用擔心天書般的系統錯誤信息。出于這個原因,異常處理是每個.NET應用程序的一個標準部分。Try/catch塊讓你能夠捕捉異常并從該點控制應用程序的執行。與數據庫進行交互操作的時候會發生很多錯誤,但是很多開發人員都不知道如何處理數據庫層的錯誤。本周我們將探討如何利用SQLServer和T-SQL來處理你數據庫代碼里的錯誤。

處理T-SQL里的錯誤

SQLServer的SQL對話讓你能夠輕松地處理可能會在存儲進程、函數里發生的非致命錯誤,但是并不是所有的錯誤都很容易處理。事實上,致命和非致命的錯誤有很多。什么是致命的,什么是非致命的,對此沒有很完備的文檔說明,但是你的應用程序代碼總是可以利用try/catch塊來處理致命的數據庫錯誤。對于其他所有的錯誤,你可以使用下面的技術。

事務

你應該在數據庫代碼里使用事務,以確保在一切都沒有問題的時候所有的更改都被完成。SQLServer的在線幫助將事務描述為任務的一個邏輯單元,它由一系列語句(選擇、插入、更新,或者刪除等)組成。如果在事務期間沒有發生任何錯誤,那么對事務的所有改動都會成為數據庫的永久部分。如果在這期間發生了錯誤,不會對數據庫進行任何修改。

事務包含在BEGIN TRANSACTION和END TRANSACTION語句之間。ROLLBACK TRANSACTION語句可以取消所有的更改,因此不會發生任何變化。用COMMIT TRANSACTION語句可以進行永久的更改。現在,就讓我們把注意力放在如何處理T-SQL里的錯誤上。

@@Error

@@Error函數讓你可以實現T-SQL錯誤處理。它會返回由系統所返回的錯誤代碼。如果沒有錯誤發生就會返回“0”。@@Error函數必須緊接在一個語句之后立即被調用,因為它會在每個T-SQL語句之后被清除。

RAISERROR

RAISERROR語句讓你能夠生成一個自定義的錯誤信息或者使用一個放在sysmessages表格里的已有消息。你可以在線查看它的句法,但是它的最基本格式包括了消息(用于自定義的消息)或者消息id(用于已有的消息)和它的嚴重度及狀態。SQLServer沒有使用狀態,所以隨便傳遞給它一個數字就可以了。嚴重度表示了錯誤的嚴重程度,0-18供用戶使用,而19-25保留給管理員使用。

在列表A里,示例存儲過程使用了這些特性來更新示例Northwind數據庫里的一條記錄:

CREATE PROCEDURE sp_UpdateCustomerPhone(

@id nvarchar(5),

@phone nvarchar(24),

@retvalueint output

) AS

BEGIN

BEGIN TRANSACTION

UPDATE [dbo].[Customers] SET [Phone] = @phone WHERE([CustomerID] = @id)

IF (@@ERROR <> 0) -- a non-negative value signals an error

BEGIN

ROLLBACK TRANSACTION -- changes are not permanent

RAISERROR('Update Customers Error',1,1) -- raise a custom error message

-- Custom error message appears if run from console

SET @retvalue = -1 -- return negative value to signalproblems

END

COMMIT TRANSACTION -- make the changes permanent, so record is updated

SET @retvalue = 1 -- a positive return value signalssuccess

RETURN

END

如果沒有錯誤發生,它就把電話號碼列設置為一個值,傳遞給過程。它使用一個返回值參數,如果有問題發生它就返回一個負值,如果用所有的東西都執行沒有問題,它會返回一個正值。

用存儲過程返回值

通過存儲過程返回值,我們可以把它用在我們的.NET代碼里。SqlCommand對象允許你很容易就添加參數傳遞給過程以及存儲返回值。參數的Direction屬性被用來接收來自存儲過程調用的值。它有兩個屬性值:InputOutput和Output。在我們的例子里,我們將使用Output來接收狀態值。

這段代碼是一個簡單的ASP.NET頁面,用來傳遞一個用于Northwind數據庫的客戶表格里某個數據的新值。而id值事實上被保存在一個隱藏字段里,可以被輕易地傳遞給表單,但是這個字段是用來說明的。在文本字段輸入的值被用更新數據庫表格里的電話號碼字段。

參數被添加給SqlCommand對象(它們必須精確地符合存儲過程的參數值)。命令通過SqlCommand對象的ExecuteNonQuery方法被執行。一旦它已經被執行,返回的值可以通過參數來取回。

代碼會檢查返回的值(-1表示有問題),而消息會顯示在一個Label控件里。此外,一個try/catch塊被用來捕捉在與數據庫進行交互操作過程中可能發生的任何致命錯誤。

利用try/catch代碼塊來處理.NET應用程序代碼里的異常是一個簡單明了的過程,但是你還可以監視數據庫層的異常。SQLServer的T-SQL語言為你處理代碼異常提供了所需要的一切。

Tony Patton的職業生涯開始于應用程序開發員,并已經獲得了證明其專業水平的Java、VB、Lotus和XML認證。

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗