SQL Server 中的異常處理

来源:https://www.cnblogs.com/broadm/archive/2022/07/13/16474428.html
-Advertisement-
Play Games

為什麼我們需要 SQL Server 中的異常處理? 讓我們通過一個示例來瞭解 SQL Server 中異常處理的必要性。因此,創建一個 SQL Server 存儲過程,通過執行以下查詢來除以兩個數字。 IF OBJECT_ID('spDivideTwoNumber','P') IS NOT NUL ...


為什麼我們需要 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)

  1. 錯誤消息 :您希望在引發異常時顯示的自定義錯誤消息。
  2. 錯誤嚴重性 :當我們在 SQL Server 中返回任何自定義錯誤時,我們需要將 ErrorSeverity 級別設置為 16,這表明這是一個一般錯誤,並且該錯誤可以由用戶更正。在我們的示例中,用戶可以通過為第二個參數提供非零值來糾正錯誤。
  3. 錯誤狀態 : 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 中的預定義錯誤術語

每當在程式中發生錯誤,例如將數字除以零、違反主鍵、違反檢查約束等,系統都會顯示一條錯誤消息,告訴我們代碼中遇到的問題。程式中發生的每個錯誤都與四個屬性相關聯。

  1. 錯誤編號
  2. 錯誤信息
  3. 嚴重程度
  4. 錯誤狀態

比如:

消息 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 遇到以零作除數錯誤。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 初學Bash時, 我從未想過去debug Bash腳本, 也從未想過Bash腳本也能debug. 隨著技術的增長, 寫的腳本越來越複雜, 使用echo列印日誌來調試腳本的方式越來越捉襟見肘了. 直到某天 通讀了一遍Bash Reference Manual, 才發現Bash腳本也是可以debug的. ...
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 問題描述: window上複製的內容無法粘貼在Linux上 環境 window64位 Ubuntu18.04 解決步驟 1、直接在命令行執行以下命令 sudo apt-get autoremove open-vm-tools //卸載已有的工具 ...
  • App Cleaner Pro是一款Mac上非常好用的軟體卸載工具,支持應用卸載、Widget卸載、瀏覽器插件卸載,支持拖拽卸載和列表卸載,能夠非常乾凈的卸載應用,節省你的磁碟空間。 詳情:App Cleaner & Uninstaller for Mac(應用程式清理卸載工具) 功能介紹 1、掃描 ...
  • 編寫背景: 本人負責某銀行的一個項目主力開發,在與第三方調試介面時遇到了一個問題:對方伺服器明明給了我返回的值,但我這邊卻沒有收到,日誌中沒有列印對應的值。一開始我認為是對方的問題,但是對方就丟了一句“我試了有的”,然後我就一個人風中凌亂。 隨即我就想到了抓包的方式進行驗證,看到底是哪一方的問題導致 ...
  • EditReady for Mac是專業高效的視頻轉碼器,擁有快速,強大的特點,可以調整視頻大小,對視頻進行旋轉,重新定時等功能,對於需要的朋友,還可以查看和編輯元數據,EditReady Mac版可以對視頻進行自定義,是非常強大的視頻轉碼器。 詳情:EditReady for Mac(專業視頻轉碼 ...
  • apache編譯安裝以及三種風格的init程式特點和區別 源碼包編譯實例 下麵通過編譯安裝httpd來深入理解源碼包安裝(httpd-2.4.54) 下載編譯工具,httpd以及其兩個依賴包的源碼包 //源碼包建議到官方網站下載 [root@lnh ~]# mkdir xbz [root@lnh ~ ...
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 Eclipse中配置maven 1.Eclipse中預設的Maven配置 可以使用預設的,本地倉庫在當前用戶下的.m2文件夾下。 2.配置我們自己安裝的maven 2.1指定配置安裝maven的路徑 2.2關聯setting.xml文件 2.3配 ...
  • DBeaverEE for Mac是一款運行在MacOS上通用的資料庫管理工具。易用性是DBeaverEE的主要目標,支持 MySQL, PostgreSQL, Oracle等常用資料庫。操作簡單,功能強大。 詳情:DBeaverEE for Mac(資料庫管理工具) 功能特點 連接到各種數據源 1 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...