為什么我們需要 SQL Server 中的例外處理?
讓我們通過一個示例來了解 SQL Server 中例外處理的必要性,因此,創建一個 SQL Server 存盤程序,通過執行以下查詢來除以兩個數字,
IF OBJECT_ID('spDivideTwoNumber','P') IS NOT NULL
DROP PROCEDURE spDivideTwoNumber
GO
CREATE PROCEDURE spDivideTwoNumber(
@Number1 INT,
@Number2 INT
)
AS
BEGIN
DECLARE @Result INT
SET @Result = 0
SET @Result = @Number1 / @Number2
PRINT '結果是:' + CAST(@Result AS VARCHAR)
END
當我們把0傳遞給這個存盤程序的第二個引數時,我們會得到一個錯誤
EXEC spDivideTwoNumber 100, 0
以下是 SQL Server Management Studio 中的輸出
訊息 8134,級別 16,狀態 1,程序 spDivideTwoNumber,第 10 行
遇到以零作除數錯誤,
結果是:0
我們可以看到,即使遇到了錯誤,SqlServer依然會繼續執行后面的陳述句,最終列印了結果是:0
所以,上述執行的問題在于,即使程式發生錯誤,它仍然顯示結果,因此用戶有可能感到困惑,
發生例外時 SQL Server 中會發生什么?
在 SQL Server 中,每當發生例外時,它都會顯示例外訊息,然后繼續執行程式,但在 C#、Java、C++ 等編程語言中,每當發生例外時,程式執行就會在例外發生的那一行例外終止,
在上述案例中,這種行為是錯誤的,因為當編程語言中發生錯誤時,它們會直接跳過錯誤后的所有陳述句的執行,但是在 SqlServer中發生錯誤后,執行不會停止,例如,在上面的存盤程序中,當例外發生時,它仍然顯示不應該發生的 “結果是:0”,
SQL Server 中的例外處理是什么?
隨著 SQL Server 2005 中引入 Try/Catch 塊,SQL Server 中的錯誤處理現在與 C# 和 Java 等編程語言非常相似,但是,在了解使用 try/catch 塊進行錯誤處理之前,讓我們退后一步,了解在 2005 年之前的 SQL Server 中如何使用系統函式 RAISERROR 和 @@Error 進行錯誤處理,
在 SQL Server 中使用 RAISERROR 系統函式處理例外
讓我們更改我們在上一個示例中創建的相同存盤程序,如下所示,以使用 Raiseerror 系統函式來處理 SQL Server 中的例外,
IF OBJECT_ID('spDivideTwoNumber','P') IS NOT NULL
DROP PROCEDURE spDivideTwoNumber
GO
CREATE PROCEDURE spDivideTwoNumber(
@Number1 INT,
@Number2 INT
)
AS
BEGIN
DECLARE @Result INT
SET @Result = 0
IF(@Number2 = 0)
BEGIN
RAISERROR('第二個數字不能為0', 16, 1)
END
ELSE
BEGIN
SET @Result = @Number1 / @Number2
PRINT '結果是: ' + CAST(@Result AS VARCHAR)
END
END
當我們再次執行以下陳述句時
EXEC spDivideTwoNumber 100, 0
以下是 SQL Server Management Studio 中的輸出
訊息 50000,級別 16,狀態 1,程序 spDivideTwoNumber,第 11 行
第二個數字不能為0
在上述程序中,如果第二個數字為零,我們使用系統定義的 Raiserror () 函式將錯誤訊息回傳給呼叫應用程式,
SQL Server 中的 RaiseError 系統函式是什么?
SQL Server 中的 RaiseError 系統定義函式采用 3 個引數,如下所示,
RAISERROR('錯誤訊息', ErrorSeverity, ErrorState)
- 錯誤訊息 :您希望在引發例外時顯示的自定義錯誤訊息,
- 錯誤嚴重性 :當我們在 SQL Server 中回傳任何自定義錯誤時,我們需要將 ErrorSeverity 級別設定為 16,這表明這是一個一般錯誤,并且該錯誤可以由用戶更正,在我們的示例中,用戶可以通過為第二個引數提供非零值來糾正錯誤,
- 錯誤狀態 : ErrorState 也是 1 到 255 之間的整數值,如果您將錯誤狀態值設定在 1 到 127 之間,RAISERROR() 函式只能生成自定義錯誤,
SQL Server 中的@@Error 系統函式
在 SQL Server 2000 中,為了檢測錯誤,我們使用了@@Error 系統函式,如果有錯誤,@@Error 系統函式回傳一個 NON-ZERO 值,否則,ZERO表示前面的SQL陳述句執行沒有任何錯誤,讓我們修改存盤程序以使用@@ERROR系統函式,如下所示,
ALTER PROCEDURE spDivideTwoNumber(
@Number1 INT,
@Number2 INT
)
AS
BEGIN
DECLARE @Result INT
SET @Result = 0
IF(@Number2 = 0)
BEGIN
RAISERROR('第二個數字不能為0',16,1)
END
ELSE
BEGIN
SET @Result = @Number1 / @Number2
END
IF(@@ERROR <> 0)
BEGIN
PRINT '發生了錯誤'
END
ELSE
BEGIN
PRINT '結果是:' + CAST(@Result AS VARCHAR)
END
END
當我們再次執行以下陳述句時
EXEC spDivideTwoNumber 100, 0
以下是 SQL Server Management Studio 中的輸出
訊息 50000,級別 16,狀態 1,程序 spDivideTwoNumber,第 11 行
第二個數字不能為0
發生了錯誤
SQL Server 中的預定義錯誤術語
每當在程式中發生錯誤,例如將數字除以零、違反主鍵、違反檢查約束等,系統都會顯示一條錯誤訊息,告訴我們代碼中遇到的問題,程式中發生的每個錯誤都與四個屬性相關聯,
- 錯誤編號
- 錯誤資訊
- 嚴重程度
- 錯誤狀態
比如:
訊息 8134(錯誤編號),級別 16(嚴重級別),狀態 1(狀態),遇到除以零錯誤(錯誤訊息)
-
錯誤編號 是為 SQL Server 中發生的每個錯誤提供的唯一識別符號,對于預定義的錯誤,該值將低于 50,000,對于用戶定義的錯誤,該值必須高于或等于 50,000,在引發自定義錯誤時,如果我們不指定錯誤編號,則默認情況下會將錯誤編號設定為 50000,
-
錯誤資訊 是描述發生的錯誤的簡短資訊,最多 2047 個字符,
-
嚴重程度 這說明錯誤的重要性,范圍在 0 到 24 之間,其中
- 0 到 9:不是服務,可被視為資訊或狀態訊息,
- 11 到 16: 表示這些錯誤可以由用戶創建,
- 17 到 19:表示這些是用戶無法糾正的軟體錯誤,必須向系統管理員報告,
- 20 到 24:表示致命錯誤,如果發生這些錯誤,可能會損壞系統或資料庫,所以這里的連接立即與資料庫終止,
-
錯誤狀態 它是一個不那么重要的任意值,可以在 0 到 127 之間,每當必須在多個地方發生相同的錯誤時,我們都會使用它,
注意:我們可以在“系統訊息”表下找到所有預定義錯誤的資訊
比如:
select * from sys.messages where language_id = 2052 and message_id = 8134
輸出如下:
| message_id | language_id | severity | is_event_logged | text |
|---|---|---|---|---|
| 8134 | 2052 | 16 | 0 | 遇到以零作除數錯誤, |
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/499184.html
標籤:SQL Server
