分享方式:


RAISERROR (Transact-SQL)

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

注意

語句 RAISERROR 不接受 SET XACT_ABORT。 新的應用程式應該使用 THROW,而非 RAISERROR

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

Transact-SQL 語法慣例

Syntax

SQL Server、Azure SQL Database、Azure SQL 受控執行個體的語法:

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 ] ]

引數

msg_id

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

msg_str

使用者定義的訊息,格式類似於 C 標準程式庫中的 printf 函數。 這個錯誤訊息最多可有 2,047 個字元。 如果訊息包含 2,048 個以上的字元,則只會顯示前 2,044 個字元:會新增省略號,以指出訊息已截斷。 替代參數會耗用比輸出顯示的字元多,因為內部記憶體行為。 例如,具有指派值的 2 替代參數%d實際上會在訊息字串中產生一個字元,但內部也會佔用三個額外的記憶體字元。 這項儲存需求減少了訊息輸出的可用字元數。

指定msg_strRAISERROR會引發錯誤訊息,錯誤號碼為 50000

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

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

可用於 msg_str 中的參數有:

旗標

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

程式碼 前置詞或對齊 描述
- (減) 靠左對齊 給定欄位寬度內的引數值靠左對齊。
+ (加) 符號前置詞 如果值是帶正負號型別,請在自變數值前面加上加號 (+) 或減號-值。
0 (零) 零填補 在輸出前加上 0,直到到達最小寬度為止。 當與減號 (-) 出現時00 會忽略 。
# (數位) 0x 或的 x 十六進位類型前置詞 X 搭配ox或 格式使用時,數字符號 (#) 旗標會分別以00xX 0X開頭任何非零值。 當 diu 前面加上數字符號 (#) 旗標時,會忽略 旗標。
' ' (空白) 空間填補 如果輸出值帶正負號且為正值時,會在輸出值前加上空格。 當加上加號 (+) 旗標時,會忽略此填補。

寬度

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

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

有效位數

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

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

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

{h | l} type

與字元類型 dioxsX、 或 u搭配使用,並建立 shortint () 或 longinthl) 值。

類型規格 表示
di 帶正負號的整數
o 不帶正負號的八進位
s String
u 不帶正負號的整數
xX 不帶正負號的十六進位

這些類型規格會以原本為 C 標準程式庫中 printf 函數定義的規格為依據。 RAISERROR 訊息字串中使用的類型規格會對應到 Transact-SQL 資料類型,而 printf 中使用的規格會對應到 C 語言資料類型。 當 Transact-SQL 沒有類似相關聯 C 資料類型的數據類型時,不支援 中使用的printfRAISERROR類型規格。 例如, %p 中不支持 RAISERROR 指標的規格,因為 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 之訊息中定義的變數。 可以有零個或多個替代參數,但替代參數總數不能超過 20。 每個替代參數都可以是區域變數或任何以下的這些資料類型:tinyintsmallintintcharvarcharncharnvarcharbinaryvarbinary。 不支援其他資料類型。

選項

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

Description
LOG 記錄錯誤記錄檔中的錯誤,以及 SQL Server 實例的應用程式記錄檔 資料庫引擎。 記錄在錯誤記錄檔中的錯誤目前最大限制為 440 位元組。 只有系統管理員固定伺服器角色的成員或具有ALTER TRACE權限的使用者可以指定 WITH LOG

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

適用於:SQL Server、Azure SQL 資料庫 和 Azure SQL 受控執行個體
SETERROR 不論嚴重性層級為何,都將 @@ERRORERROR_NUMBER 值設定為 msg_id 或 50000。

適用於:SQL Server、Azure SQL 資料庫 和 Azure SQL 受控執行個體

備註

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

  • 在任何 TRY 區塊的範圍之外。
  • TRY 區塊中具備 10 或更低的嚴重性。
  • 以會結束資料庫連接的 20 或更高的嚴重性執行。

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

當msg_id指定目錄檢視中可用的sys.messages使用者定義訊息時RAISERROR請使用與套用至使用 msg_str 所指定之使用者定義訊息的文字相同的規則,處理來自文字數據行的訊息。 使用者定義的消息正文可以包含轉換規格,並將 RAISERROR 自變數值對應至轉換規格。 使用 sp_addmessage 來新增使用者定義的錯誤訊息,以及使用 sp_dropmessage 來刪除使用者定義的錯誤訊息。

RAISERROR 可用來作為將訊息傳回呼叫應用程式的替代 PRINT 方法。 RAISERROR 支持類似 C 標準連結庫中函式功能的 printf 字元替代,而 Transact-SQL PRINT 語句則不支援。 語句 PRINT 不會受到 TRY 區塊的影響,而 RAISERROR TRY 區塊中的執行嚴重性為 11 到 19,則會將控制權傳輸至相關聯的 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 的嚴重性層級只能由系統管理員固定伺服器角色的成員或具有許可權的使用者指定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.messages 訊息。 訊息已新增至 sys.messages 目錄檢視,方法是使用 sp_addmessage 系統預存程式做為訊息編號 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