| 函數 | 返回值 | 示例 |
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... |
事務控制模式
模式 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) | 新模式 (TRY...CATCH) |
| 多語句事務 | 每句檢查、標誌變量、GOTO 清理標籤 | 整塊包裹、自動/顯式回滾、代碼清晰 |
| 嵌套存儲過程 | 返回碼傳遞、極易丟失上下文 | 錯誤向上冒泡、外層統一捕獲 |
| 死鎖重試 | WHILE 循環 + @@ERROR=1205 + WAITFOR | CATCH 判斷 1205 → 重試邏輯、更優雅 |
| 錯誤日誌 | 手動拼湊信息、不完整 | ERROR_* 函數標準化、完整上下文 |
最佳實踐清單
- 所有存儲過程/觸發器/批次強制使用 TRY...CATCH。
- 默認開啟
SET XACT_ABORT ON(腳本/過程首行)。
- CATCH 內優先記錄錯誤,再決定重新拋出 (
THROW) 或吞噬。
- 錯誤日誌表包含:時間、SPID、登錄名、應用名、錯誤號/嚴重級/狀態/過程/行/消息、命令文本 (可選)。
- 死鎖 (1205) 實現指數退避重試 (最多 3 次),記錄重試次數。
- 嚴重級 20+ 錯誤無法捕獲,需依賴 Extended Events / SQL Agent Alert / Windows 事件日誌 監控。
結語
TRY...CATCH 將 T-SQL 錯誤處理從「手工拼湊」提升至「結構化工程」層面。配合 XACT_ABORT ON、THROW、標準化錯誤日誌、死鎖重試模式,構建生產級健壯數據庫程式碼的基石。
- 上一篇文章: SQL Server 2005 T-SQL 增強特性深度解析:大值類型、XML 原生、TRY...CATCH 異常處理
- 下一篇文章: SQL Server 2005 數據加密技術體系深度解析:多級密鑰架構、對稱/非對稱/證書與 DPAPI 保護鏈
Copyright ©
程式碼之家 All Rights Reserved