語法
RAISERROR ( { msg_id | msg_str | @local_variable }
{ , severity , state }
[ , argument [ ,...n ] ] )
[ WITH option [ ,...n ] ]
參數詳細說明
| 參數 | 說明 |
msg_id | sys.messages 中的訊息編號 (用戶自訂需 > 50000),透過 sp_addmessage 新增。 |
msg_str | 使用者自訂訊息字串 (最長 2047 字元),常數建議用 N'...' (nvarchar)。引發錯誤號固定為 50000。 |
@local_variable | 符合 msg_str 格式的區域變數。 |
severity | 嚴重等級:0-10 為資訊/警告 (不進 CATCH);11-19 進 CATCH;20+ 終止連線 (需 sysadmin)。 |
state | 1-127 之間整數,用於區分同一錯誤在不同程式碼位置被引發 (預設 1)。 |
argument | 代入 msg_str 佔位符 (如 %s, %d) 的參數。 |
option | LOG (寫入錯誤記錄檔)、NOWAIT (立即傳送用戶端)、SETERROR (設定 @@ERROR/ERROR_NUMBER)。 |
七大實戰範例
範例 1:變數代入訊息
DECLARE @raiseErrorCode nvarchar(50) = CONVERT(nvarchar(50), @SomeUniqueKey);
RAISERROR('%s INVALID ID. There is no record in table', 16, 1, @raiseErrorCode);
範例 2:多參數格式化
RAISERROR (N'This is message %s %d.', 10, 1, N'number', 5);
-- 回傳:This is message number 5.
範例 3:寬度與精度格式化
RAISERROR (N'<<%*.*s>>', 10, 1, 7, 3, N'abcde');
-- 回傳:<< abc>> (寬度 7, 精度 3)
範例 4:直接指定寬度精度
RAISERROR (N'<<%7.3s>>', 10, 1, N'abcde'); -- 同範例 3
範例 5:TRY...CATCH 中重新拋出原始錯誤
BEGIN TRY
RAISERROR ('Error raised in TRY block.', 16, 1);
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000) = ERROR_MESSAGE(),
@ErrorSeverity INT = ERROR_SEVERITY(),
@ErrorState INT = ERROR_STATE();
RAISERROR (@ErrorMessage, @ErrorSeverity, @ErrorState);
END CATCH;
範例 6:sys.messages 登錄自訂錯誤並引發
sp_addmessage @msgnum = 50005, @severity = 10, @msgtext = N'<<%7.3s>>'; GO
RAISERROR (50005, 10, 1, N'abcde'); -- 回傳 << abc>>
sp_dropmessage @msgnum = 50005; GO
範例 7:區域變數提供訊息文本 (同範例 6)
DECLARE @msg NVARCHAR(200) = N'<<%7.3s>>';
RAISERROR (@msg, 10, 1, N'abcde');
最佳實務
- 業務邏輯驗證失敗 →
RAISERROR(..., 16, 1) 進入 CATCH 統一處理。
- 嚴重等級 ≥ 20 需
WITH LOG 且僅限 sysadmin,慎用。
state 為每個引發點指定唯一值,利於除錯定位。