SQL Server 2008之錯誤處理


  1. 錯誤可能發生執行的各個階段,包括語法檢查階段、對象名稱識別階段、語句執行階段;錯誤即可以在數據庫引擎中處理,也可以在應用程序中處理
  2. 錯誤類型,根據錯誤發生時機區分:
  • Syntax Errors,語法錯誤
  • Object Resolution Errors,對象識別錯誤
  • Statement Terminating Errors,語句終止錯誤,發生錯誤的下一條語句繼續執行
  • BatchConnectionServer Terminating Errors,通常都是非常嚴重的錯誤,比如硬件錯誤,非常少見
  1. 錯誤本身也是一個對象,具有如下屬性:
  • Error number:唯一的錯誤編碼
  • Error Message:錯誤信息,經過了本地化,使用sys.messages視圖查看信息時,為每個message_id(即Error number)返回對個message,每個message對應不同的language_id,即對應不同語言
  • Severity,嚴重性
  • State,決定發生錯誤的代碼的位置,是在代碼中中由開發者定義的,在raise error中可以指定一個state
  • Procedure Name,存儲過程或者觸發器的名稱,如果有的話
  • Line Number,表明發生錯誤的代碼行
  1. 錯誤嚴重性:
  • 0-9,信息
  • 10,返回狀態的信息
  • 11-16,需要用戶糾正的錯誤,比如11表示對象不存在,13表示事務死鎖,14表示像沒有權限這樣的錯誤,15表示語法錯誤
  • 17-19,用戶無法糾正的軟件錯誤,比如17表示資源用盡(比如內存、磁盤空間、鎖等資源)
  • 20-24,嚴重的系統錯誤
  • 25SQL Server服務終端錯誤
  1. RAISE ERRORPRINT都可以返回信息或者錯誤,PRINT相當於返回Severity10的信息;%d是數字占位符,%s是字符串占位符;有兩種方式,一種是使用sp_addmessage創建用戶自定義的錯誤信息,一種是指定錯誤字符串,此時error number總是5000
  2. @@ERROR是一個系統變量,保存上次發生錯誤的error number,如果語句成功執行返回0,否則返回error number,每個語句執行完都要修改該值,因為只要錯誤一出現就要盡快捕獲該值
  3. 大部分錯誤是語句終止錯誤,即只有發生錯誤的語句回滾,然后繼續執行下一條語句;當設置SET XACT_ABORT ON語句時,語句終止錯誤應該變為批處理終止錯誤,即語句發生錯誤時,整個批處理進行回滾,而不僅僅是單個語句回滾
  4. SQL Server不支持自治事務autonomous transactions,自治事務就是不在同一個范圍內的嵌套事務,其提交和回滾不影響外部事務;@@TRANCOUNT系統變量返回事務嵌套層級,存儲過程要求在開始和退出時@@TRANCOUNT必須是一致的,否則拋出錯誤286,通常用來防止嵌套事務
  5. sp_addmessage允許添加自定義的錯誤信息,指定的error number必須是50000或者以上,可以指定語言(@lang參數),@with_log設置為true時,返回錯誤時會將錯誤記錄到Windows Application log@replace用於替換已有的自定義消息的Message,使用該系統存儲過程時,必須具有sysadmin或者serveradmin權限;注意不能引發系統錯誤
  6.  BEGIN CATCH語句必須跟在END TRY之后;在T-SQL中沒有等價於FINALLY的語句,沒有rethrowing機制,只有大於50000的錯誤可以手工拋出,即不能在CATCH語句中引發一個系統錯誤
  7. CATCH語句塊為捕獲錯誤信息提供了比@@ERROR更豐富的選擇,可以在CATCH語句塊中執行錯誤處理函數,返回錯誤信息,錯誤處理函數還可以定義成存儲過程以便重用,這些錯誤處理函數在整個CATCH語句塊中始終都保持同一個值,不存在像@@ERROR值被輕易修改的問題
  8. 不是所有的錯誤都可以在當前范圍的TRY/CATCH語句塊中捕獲,通常來說,在當前范圍不能捕獲的錯誤,可以在包含他們的范圍內捕獲,比如不能在存儲過程內部TRY/CATCH語句塊中捕獲的錯誤,可以在調用存儲過程的TRY/CATCH語句塊中捕獲;通常不能捕獲的錯誤包括:編譯錯誤、語句級別重新編譯問題(通常是名稱識別錯誤)
  9. CATCH語句塊不會自動回滾異常,需要在CATCH語句塊中手動回滾異常
  10. 通常來說盡量在托管代碼中捕獲異常,所有托管代碼中未捕獲的異常,傳遞到T-SQL代碼中都是一個6522的錯誤,錯誤信息可以嵌套,SQL CLR Messages需要解包去找到內部錯誤,而不是封裝的6522錯誤,托管代碼中也可以執行RAISERROR語句


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM