首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

T-SQL TRY...CATCH 異常處理實戰指南:語法規則、錯誤函數、事務控制與遷移最佳實踐

     編輯:關於SqlServer

核心語法規則

  • BEGIN TRY ... END TRY BEGIN CATCH ... END CATCH 必須成對、相鄰,中間無其他語句。
  • 不可嵌套,但可調用含 TRY...CATCH 的存儲過程(錯誤向上傳遞)。
  • TRY 內無錯誤 → 跳過 CATCH,執行後續語句。
  • CATCH 內執行完 → 執行後續語句(除非 THROW/RETURN/GOTO)。

錯誤信息函數 (僅在 CATCH 內有效)

事務控制模式

模式 A:XACT_ABORT ON + 隱式回滾


SET XACT_ABORT ON;
BEGIN TRY
    BEGIN TRAN;
    -- 邏輯
    COMMIT TRAN;
END TRY
BEGIN CATCH
    -- 此時事務已自動回滾 (XACT_ABORT 效果)
    -- 僅需記錄/告警
    INSERT INTO ErrorLog ... VALUES (ERROR_NUMBER(), ERROR_MESSAGE(), ...);
END CATCH

模式 B:顯式事務控制 (靈活)


BEGIN TRY
    BEGIN TRAN;
    -- 邏輯
    COMMIT TRAN;
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0 ROLLBACK TRAN; -- 必須顯式回滾
    -- 處理
END CATCH

遷移對比:舊模式 vs 新模式

函數返回值示例
ERROR_NUMBER()錯誤號 (如 547 外鍵衝突)547
ERROR_SEVERITY()嚴重級 (11-19 可捕獲)16
ERROR_STATE()狀態碼 (區分同錯誤號不同位置)1
ERROR_PROCEDURE()觸發錯誤的存儲過程/觸發器名usp_InsertOrder
ERROR_LINE()批次/過程內行號42
ERROR_MESSAGE()完整錯誤文本The INSERT statement conflicted with FOREIGN KEY...
場景舊模式 (@@ERROR)新模式 (TRY...CATCH)
多語句事務每句檢查、標誌變量、GOTO 清理標籤整塊包裹、自動/顯式回滾、代碼清晰
嵌套存儲過程返回碼傳遞、極易丟失上下文錯誤向上冒泡、外層統一捕獲
死鎖重試WHILE 循環 + @@ERROR=1205 + WAITFORCATCH 判斷 1205 → 重試邏輯、更優雅
錯誤日誌手動拼湊信息、不完整ERROR_* 函數標準化、完整上下文

最佳實踐清單

  1. 所有存儲過程/觸發器/批次強制使用 TRY...CATCH。
  2. 默認開啟 SET XACT_ABORT ON(腳本/過程首行)。
  3. CATCH 內優先記錄錯誤,再決定重新拋出 (THROW) 或吞噬。
  4. 錯誤日誌表包含:時間、SPID、登錄名、應用名、錯誤號/嚴重級/狀態/過程/行/消息、命令文本 (可選)。
  5. 死鎖 (1205) 實現指數退避重試 (最多 3 次),記錄重試次數。
  6. 嚴重級 20+ 錯誤無法捕獲,需依賴 Extended Events / SQL Agent Alert / Windows 事件日誌 監控。

結語

TRY...CATCH 將 T-SQL 錯誤處理從「手工拼湊」提升至「結構化工程」層面。配合 XACT_ABORT ON、THROW、標準化錯誤日誌、死鎖重試模式,構建生產級健壯數據庫程式碼的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved