使用 RAISERROR
RAISERROR 是用來將訊息傳回給應用程式,格式與 SQL Server Database Engine 所產生的系統錯誤或警告訊息相同。
RAISERROR 可傳回:
使用 sp_addmessage 系統預存程序所建立的使用者定義錯誤訊息。這些訊息的訊息編號都大於 50000,您可以在 sys.messages 目錄檢視中看到這些訊息編號。
在 RAISERROR 陳述式中指定的訊息字串。
RAISERROR 亦可:
指派特定錯誤號碼、嚴重性和狀態。
要求在 Database Engine 錯誤記錄檔和 Microsoft Windows 應用程式記錄檔中記錄錯誤。
將引數值替代到訊息文字中,這項功能類似於 C 語言的 printf_s 函數。
RAISERROR 和 PRINT 都可用來將資訊或警告訊息傳回給應用程式。可以使用與 C 標準程式庫中 printf_s 函數類似的功能來建立 RAISERROR 傳回的訊息文字,而 PRINT 則只能傳回字元字串或字元運算式。如果 TRY…CATCH 建構的 TRY 區塊中執行嚴重性為 11 到 19 的 RAISERROR,則控制權會轉交給相關聯的 CATCH 區塊。指定 10 或 10 以下的嚴重性會直接使用 RAISERROR 傳回訊息,而不叫用 CATCH 區塊。PRINT 不會將控制權轉交給 CATCH 區塊。
當 RAISERROR 搭配 sys.messages 中使用者定義訊息的 msg_id 使用時,msg_id 會傳回為 SQL Server 錯誤號碼或原生錯誤碼。如果 RAISERROR 是用來搭配 msg_str,而非 msg_id,則傳回的 SQL Server 錯誤號碼和原生錯誤碼為 50000。
使用 RAISERROR 來傳回使用者自訂錯誤訊息時,請在參考該錯誤的每個 RAISERROR 中使用不同的狀態編號。萬一發生錯誤時,這可協助您診斷原因。
使用 RAISERROR 可:
協助疑難排解 Transact-SQL 程式碼。
檢查資料的值。
傳回包含變數文字的訊息。
將執行位置從 TRY 區塊跳到相關聯的 CATCH 區塊。
從 CATCH 區塊將錯誤資訊傳回給呼叫的批次或應用程式。
下例會在傳回應用程式的訊息中替換 DB_ID() 和 DB_NAME() 函數的值:
DECLARE @DBID INT;
SET @DBID = DB_ID();
DECLARE @DBNAME NVARCHAR(128);
SET @DBNAME = DB_NAME();
RAISERROR
(N'The current database ID is:%d, the database name is: %s.',
10, -- Severity.
1, -- State.
@DBID, -- First substitution argument.
@DBNAME); -- Second substitution argument.
GO
這個範例以使用者自訂的訊息提供同樣的資訊:
EXECUTE sp_dropmessage 50005;
GO
EXECUTE sp_addmessage 50005, -- Message id number.
10, -- Severity.
N'The current database ID is: %d, the database name is: %s.';
GO
DECLARE @DBID INT;
SET @DBID = DB_ID();
DECLARE @DBNAME NVARCHAR(128);
SET @DBNAME = DB_NAME();
RAISERROR (50005,
10, -- Severity.
1, -- State.
@DBID, -- First substitution argument.
@DBNAME); -- Second substitution argument.
GO
下列程式碼範例會顯示如何在 TRY 區塊內利用 RAISERROR,來使執行跳到相關聯的 CATCH 區塊。它也會顯示如何使用 RAISERROR 來傳回可叫用 CATCH 區塊的錯誤相關資訊。
[!附註]
RAISERROR 只能產生狀態為 1 到 127 的錯誤。因為 Database Engine 可能會引發狀態為 0 的錯誤,我們建議您在傳送 ERROR_STATE 的值給 RAISERROR 的狀態參數之前,先檢查它傳回的錯誤狀態。
BEGIN TRY
-- RAISERROR with severity 11-19 will cause execution to
-- jump to the CATCH block
RAISERROR ('Error raised in TRY block.', -- Message text.
16, -- Severity.
1 -- State.
);
END TRY
BEGIN CATCH
DECLARE @ErrorMessage NVARCHAR(4000);
DECLARE @ErrorSeverity INT;
DECLARE @ErrorState INT;
SELECT @ErrorMessage = ERROR_MESSAGE(),
@ErrorSeverity = ERROR_SEVERITY(),
@ErrorState = ERROR_STATE();
-- Use RAISERROR inside the CATCH block to return
-- error information about the original error that
-- caused execution to jump to the CATCH block.
RAISERROR (@ErrorMessage, -- Message text.
@ErrorSeverity, -- Severity.
@ErrorState -- State.
);
END CATCH;