RAISERROR (Transact-SQL)

適用於:Microsoft Fabric 中 Microsoft Fabric倉儲中的 SQL ServerAzure SQL 資料庫 Azure SQL 受控執行個體 Azure SynapseAnalytics Analytics Platform System (PDW)SQL 分析端點

注意

RAISERROR 陳述式不受 SET XACT_ABORT 影響。 新的應用程式應該使用 THROW,而非 RAISERROR

產生錯誤訊息並起始工作階段的錯誤處理。 RAISERROR 可以參考儲存在 sys.messages 目錄檢視中使用者定義的訊息,也可以動態建置訊息。 該訊息會以伺服器錯誤訊息的形式傳回給呼叫的應用程式,或傳回給 TRY...CATCH 建構的相關聯 CATCH 區塊。 新應用程式應該改用 THROW

Transact-SQL 語法慣例

語法

SQL Server 和 Azure SQL Database 的語法:

RAISERROR ( { msg_id | msg_str | @local_variable }
    { , severity, state }
    [ , argument [ , ...n ] ] )
    [ WITH option [ , ...n ] ]

Azure Synapse Analytics 和平行處理資料倉儲的語法:

RAISERROR ( { msg_str | @local_variable }
    { , severity, state }
    [ , argument [ , ...n ] ] )
    [ WITH option [ , ...n ] ]

注意

若要檢視 SQL Server 2014 (12.x) 和舊版的 Transact-SQL 語法,請參閱 舊版檔

引數

msg_id

這是使用 sp_addmessage 儲存在 sys.messages 目錄檢視中使用者定義的錯誤訊息編號。 使用者自訂錯誤訊息的錯誤號碼應該大於 50000。 如果未指定 msg_idRAISERROR 就會引發錯誤號碼為 50000 的錯誤訊息。

msg_str

使用者定義的訊息,格式類似於 C 標準程式庫中的 printf 函數。 這個錯誤訊息最多可有 2,047 個字元。 如果訊息包含 2,048 個或更多字元,則只會顯示前 2,044 個字元,並且會加上省略符號以表示該訊息已被截斷。 請注意,由於內部儲存行為的緣故,替代參數比輸出顯示耗用更多字元。 例如,指派值為 2 的 %d 替代參數,實際上會在訊息字串中產生一個字元,但在內部卻也佔用了三個額外儲存字元。 這項儲存需求減少了訊息輸出的可用字元數。

指定 msg_str 時,RAISERROR 就會引發錯誤號碼為 50000 的錯誤訊息。

msg_str 是具有選擇性內嵌轉換規格的字元字串。 每一轉換規格定義了引數清單中的值如何格式化,以及如何置入位於 msg_str 中轉換規格的欄位。 轉換規格具有這個格式:

% [[旗標] [寬度] [. 有效位數] [{h | l}]] 類型

可用於 msg_str 中的參數有:

旗標

決定替代值之間距與對齊的程式碼。

程式碼 前置詞或對齊 描述
- (減號) 靠左對齊 給定欄位寬度內的引數值靠左對齊。
+ (加號) 符號前置詞 如果值為帶正負號的類型,則在引數值前加上正號 (+) 或負號 (-)。
0 (零) 零填補 在輸出前加上 0,直到到達最小寬度為止。 當 0 與減號 (-) 出現時,0 會被忽略。
# (數字) x 或 X 之十六進位類型的 0x 前置詞 使用 o、x 或 X 格式時,數字符號 (#) 旗標會分別在非零值前面加上 0、0x 或 0X。 當在 d、i 或 u 前面加上數字符號 (#) 旗標時,該旗標會被忽略。
' ' (空白) 空間填補 如果輸出值帶正負號且為正值時,會在輸出值前加上空格。 如果包含了正號 (+) 旗標時,這個空格會被忽略。

寬度

定義引數值所在欄位最小寬度的整數。 如果引數值的長度等於或長於「寬度」 ,則列印出的值不帶填補。 如果值短於「寬度」 ,則會將值填補至「寬度」 中指定的長度。

星號 (*) 表示寬度是由引數清單中相關聯的引數所指定,必須是整數值。

有效位數

從字串值的引數值中取得的最大字元數。 例如,如果字串有五個字元而有效位數為 3,則只會使用字串值的前三個字元。

至於整數值,「有效位數」 是列印出的最少小數位數。

星號 (*) 表示有效位數是由引數清單中相關聯的引數所指定,必須是整數值。

{h | l} type

搭配字元類型 d、i、o、s、x、X 或 u 使用,並建立 shortint (h) 或 longint (l) 值。

類型規格 表示
d 或 i 帶正負號的整數
o 不帶正負號的八進位
s String
u 不帶正負號的整數
x 或 X 不帶正負號的十六進位

這些類型規格會以原本為 C 標準程式庫中 printf 函數定義的規格為依據。 RAISERROR 訊息字串中使用的類型規格會對應到 Transact-SQL 資料類型,而 printf 中使用的規格會對應到 C 語言資料類型。 當 Transact-SQL 沒有類似於相關聯 C 資料類型的資料類型時,RAISERROR 不支援 printf 中使用的類型規格。 例如,RAISERROR 不支援指標的 %p 規格,因為 Transact-SQL 沒有指標資料類型。

若要將值轉換為 Transact-SQL bigint 資料類型,請指定 %I64d

@local_variable

這是任何有效字元資料類型的變數,其中包含採用與 msg_str 相同方法格式化的字串。 @local_variable 必須是 charvarchar,或者能夠隱含轉換為這些資料類型。

severity

與此訊息相關聯之使用者定義的嚴重性層級。 使用 msg_id 來引發使用 sp_addmessage 建立的使用者定義訊息時,RAISERROR 上指定的嚴重性會覆寫 sp_addmessage 中指定的嚴重性。

因為從 19 到 25 的嚴重性層級需要 WITH LOG 選項。 小於 0 的嚴重性層級會被解譯為 0。 大於 25 的嚴重性層級會被解譯為 25。

警告

從 20 到 25 的嚴重性層級是極嚴重的。 如果遇到嚴重的嚴重性層級,用戶端連接會在收到訊息之後中斷,而該錯誤會記錄在錯誤和應用程式記錄檔中。

您可以指定 -1,以傳回與錯誤相關聯的嚴重性值,如下列範例所示。

RAISERROR (15600, -1, -1, 'mysp_CreateCustomer');

以下為結果集。

Msg 15600, Level 15, State 1, Line 1
An invalid parameter or option was specified for procedure 'mysp_CreateCustomer'.

state

0 到 255 之間的整數。 負值預設為 1。 不應使用大於 255 的值。

如果相同的使用者自訂錯誤在多個位置引發,針對每個位置使用唯一的狀態碼可以協助您找出引發錯誤的程式碼區段。

引數

這些參數可用來替代 msg_str 或對應到 msg_id 之訊息中定義的變數。 可以有 0 或更多的替代參數,但是替代參數的總數不能超過 20。 每個替代參數都可以是區域變數或任何以下的這些資料類型:tinyintsmallintintcharvarcharncharnvarcharbinaryvarbinary。 不支援其他資料類型。

選項

錯誤的自訂選項,可以是下表的其中一個值。

描述
LOG 在 Microsoft SQL Server 資料庫引擎執行個體的錯誤記錄檔和應用程式記錄檔中記錄錯誤。 記錄在錯誤記錄檔中的錯誤目前最大限制為 440 位元組。 只有系統管理員 (sysadmin) 固定伺服器角色成員,或具有 ALTER TRACE 權限的使用者,才可以指定 WITH LOG。

適用於:SQL Server
NOWAIT 立即傳送訊息給用戶端。

適用範圍: SQL Server、SQL Database
SETERROR 不論嚴重性層級為何,都將 @@ERRORERROR_NUMBER 值設定為 msg_id 或 50000。

適用範圍: SQL Server、SQL Database

備註

RAISERROR 產生的錯誤,運作方式和由資料庫引擎程式碼所產生的錯誤相同。 RAISERROR 指定的值是由 ERROR_LINEERROR_MESSAGEERROR_NUMBERERROR_PROCEDUREERROR_SEVERITYERROR_STATE@@ERROR 系統函數所報告。 在 TRY 區塊中以 11 或更高的嚴重性來執行 RAISERROR 時,其會將控制項傳送到相關聯的 CATCH 區塊。 如果執行 RAISERROR,就會將錯誤傳回給呼叫端:

  • 在任何 TRY 區塊的範圍之外。

  • TRY 區塊中具備 10 或更低的嚴重性。

  • 以會結束資料庫連接的 20 或更高的嚴重性執行。

CATCH 區塊可以使用 RAISERROR 來重新擲出錯誤,此錯誤可透過使用 ERROR_NUMBERERROR_MESSAGE 等系統函數擷取原來的錯誤資訊,來叫用 CATCH 區塊。 對於嚴重性從 1 到 10 的訊息,@@ERROR 預設會設定為 0。

msg_id 指定可從 sys.messages 目錄檢視取得的使用者定義訊息時,RAISERROR 在處理文字資料行的訊息時使用的規則,會與套用到使用 msg_str 指定之使用者定義訊息文字的規則相同。 使用者定義的訊息文字可以包含轉換規格,而且 RAISERROR 會將引數值對應到轉換規格。 使用 sp_addmessage 來新增使用者定義的錯誤訊息,以及使用 sp_dropmessage 來刪除使用者定義的錯誤訊息。

RAISERROR 可以用來作為 PRINT 的替代方法,以將訊息傳回給呼叫的應用程式。 RAISERROR 支援類似於 C 標準程式庫中 printf 函數功能的字元替代,而 Transact-SQL PRINT 陳述式則不支援。 PRINT 陳述式不會受到 TRY 區塊影響,而在 TRY 區塊中以嚴重性 11 到 19 執行的 RAISERROR 會將控制項傳送給相關聯的 CATCH 區塊。 若要使用 RAISERROR 傳回來自 TRY 區塊的訊息,而不叫用 CATCH 區塊,請指定 10 或更低的嚴重性。

通常連續引數會取代連續轉換規格;第一個引數會取代第一個轉換規格,第二個引數會取代第二個轉換規格,依此類推。 例如,在下列 RAISERROR 陳述式中,N'number' 的第一個引數會取代 %s 的第一個轉換規格,而第二個引數 5 則會取代 %d. 的第二個轉換規格。

RAISERROR (N'This is message %s %d.', -- Message text.
           10, -- Severity,
           1, -- State,
           N'number', -- First argument.
           5); -- Second argument.
-- The message text returned is: This is message number 5.
GO

如果為轉換規格的寬度或精確度指定星號 (*),則會將要用於寬度或精確度的值指定為整數引數值。 在這個情況下,一個轉換規格最多可使用三個引數,分別是寬度、有效位數和替代值。

例如,下列兩個 RAISERROR 陳述式都會傳回相同的字串。 一個在引數清單中指定寬度和有效位數值;另一個在轉換規格中指定寬度和有效位數值。

RAISERROR (N'<\<%*.*s>>', -- Message text.
           10, -- Severity,
           1, -- State,
           7, -- First argument used for width.
           3, -- Second argument used for precision.
           N'abcde'); -- Third argument supplies the string.
-- The message text returned is: <<    abc>>.
GO
RAISERROR (N'<\<%7.3s>>', -- Message text.
           10, -- Severity,
           1, -- State,
           N'abcde'); -- First argument supplies the string.
-- The message text returned is: <<    abc>>.
GO

權限

任何使用者皆可指定從 0 到 18 的嚴重性層級。 從 19 到 25 的嚴重性層級只能由系統管理員 (sysadmin) 固定伺服器角色成員或具有 ALTER TRACE 權限的使用者來指定。

範例

A. 從 CATCH 區塊傳回錯誤資訊

下列程式碼範例顯示如何在 RAISERROR 區塊內使用 TRY,使執行位置跳到相關聯的 CATCH 區塊。 這個範例也會顯示如何利用 RAISERROR,來傳回叫用 CATCH 區塊之錯誤的相關資訊。

注意

RAISERROR 只會產生狀態從 1 到 127 的錯誤。 因為資料庫引擎可能會引發狀態為 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;

B. 在 sys.messages 中建立特定訊息

下列範例會顯示如何引發儲存在 sys.message 目錄檢視表的訊息。 使用 sp_addmessage 系統預存程序,可將訊息加入 sys.messages 目錄檢視表中成為訊息編號 50005

EXEC sp_addmessage @msgnum = 50005,
              @severity = 10,
              @msgtext = N'<\<%7.3s>>';
GO
RAISERROR (50005, -- Message id.
           10, -- Severity,
           1, -- State,
           N'abcde'); -- First argument supplies the string.
-- The message text returned is: <<    abc>>.
GO
EXEC sp_dropmessage @msgnum = 50005;
GO

C. 使用區域變數來提供訊息文字

下列程式碼範例會顯示如何使用本機變數為 RAISERROR 陳述式提供訊息文字。

DECLARE @StringVariable NVARCHAR(50);
SET @StringVariable = N'<\<%7.3s>>';

RAISERROR (@StringVariable, -- Message text.
           10, -- Severity,
           1, -- State,
           N'abcde'); -- First argument supplies the string.
-- The message text returned is: <<    abc>>.
GO

另請參閱