RAISERROR (Transact-SQL)

洪岐發表於2010-11-20

來源:

SQL Server 2005 聯機叢書

生成錯誤訊息並啟動會話的錯誤處理。RAISERROR 可以引用 sys.messages 目錄檢視中儲存的使用者定義訊息,也可以動態建立訊息。該訊息作為伺服器錯誤訊息返回到呼叫應用程式,或返回到 TRY…CATCH 構造的關聯 CATCH 塊。


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

備註
<?XML:NAMESPACE PREFIX = [default] http://ddue.schemas.microsoft.com/authoring/2003/5 NS = "http://ddue.schemas.microsoft.com/authoring/2003/5" />

RAISERROR 生成的錯誤與資料庫引擎 程式碼生成的錯誤的執行方式相同。RAISERROR 指定的值由 ERROR_LINE、ERROR_MESSAGE、ERROR_NUMBER、ERROR_PROCEDURE、ERROR_SEVERITY、ERROR_STATE 以及 @@ERROR 等系統函式來報告。當 RAISERROR 在嚴重級別為 11 或更高的情況下在 TRY 塊中執行,它便會將控制傳輸至關聯的 CATCH 塊。如果 RAISERROR 在下列情況下執行,便會將錯誤返回到呼叫方:


在任何 TRY 塊的作用域之外執行。
在嚴重級別為 10 或更低的情況下在 TRY 塊中執行。
在嚴重級別為 20 或更高的情況下終止資料庫連線。

CATCH 塊可以使用 RAISERROR 來再次引發呼叫 CATCH 塊的錯誤,方法是使用 ERROR_NUMBER 和 ERROR_MESSAGE 之類的系統函式檢索原始錯誤訊息。對於嚴重級別為 1 到 10 的訊息,@@ERROR 預設值為 0。有關詳細資訊,請參閱在 Transact-SQL 中使用 TRY...CATCH。

當 msg_id 指定 sys.messages 目錄檢視中可用的使用者定義訊息時,RAISERROR 按照與應用到使用 msg_str 指定的使用者定義訊息文字的規則相同的規則處理文字列中的訊息。使用者定義訊息文字可以包含轉換規格,並且 RAISERROR 將引數值對映到轉換規格。使用 sp_addmessage 新增使用者定義錯誤訊息,而使用 sp_dropmessage 刪除使用者定義錯誤訊息。

RAISERROR 可以替代 PRINT 將訊息返回到呼叫應用程式。RAISERROR 支援類似於 C 標準庫中 printf 函式功能的字元替代,而 Transact-SQL PRINT 語句則不支援。PRINT 語句不受 TRY 塊的影響,而在嚴重級別為 11 到 19 的情況下在 TRY 塊中執行的 RAISERROR 會將控制傳輸至關聯的 CATCH 塊。指定嚴重級別為 10 或更低以使用 RAISERROR 返回 TRY 塊中的訊息,而不必呼叫 CATCH 塊。

通常,連續的引數替換連續的轉換規格;第一個引數替換第一個轉換規格,第二個引數替換第二個轉換規格,以此類推。例如,在以下 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


引數
msg_id

使用 sp_addmessage 儲存在 sys.messages 目錄檢視中的使用者定義錯誤訊息號。使用者定義錯誤訊息的錯誤號應當大於 50000。如果未指定 msg_id,則 RAISERROR 引發一個錯誤號為 50000 的錯誤訊息。

msg_str

使用者定義訊息,格式與 C 標準庫中的 printf 函式類似。該錯誤訊息最長可以有 2,047 個字元。如果該訊息包含的字元數等於或超過 2,048 個,則只能顯示前 2,044 個並新增一個省略號以表示該訊息已被截斷。請注意,由於內部儲存行為的緣故,替代引數使用的字元數比輸出所顯示的字元數要多。例如,賦值為 2 的代替引數 %d 實際在訊息字串中生成一個字元,但是還會在內部佔用另外三個儲存字串。此儲存要求減少了可用於訊息輸出的字元數。

當指定 msg_str 時,RAISERROR 將引發一個錯誤號為 5000 的錯誤訊息。

msg_str 是一個字串,具有可選的嵌入轉換規格。每個轉換規格都會定義引數列表中的值如何格式化並將其置於 msg_str 中轉換規格位置上的欄位中。轉換規格的格式如下:

% [[flag] [width] [. precision] [{h | l}]] type

可在 msg_str 中使用的引數包括:

flag

用於確定被替換值的間距和對齊的程式碼。


程式碼 字首或對齊 說明

-(減號)

左對齊

在給定欄位寬度內左對齊引數值。

+(加號)

符號字首

如果引數值為有符號型別,則在引數值的前面加上加號(+)或減號(-)。

0(零)

零填充

在達到最小寬度之前在輸出前面加上零。如果出現 0 和減號 (-),將忽略 0。

#(數字)

對 x 或 X 的十六進位制型別使用 0x 字首

當使用 o、x 或 X 格式時,數字符號 (#) 標誌在任何非零值的前面分別加上 0、0x 或 0X。當 d、i 或 u 的前面有數字符號 (#) 標誌時,將忽略該標誌。

' '(空格)

空格填充

如果輸出值有符號且為正,則在該值前加空格。如果包含在加號(+)標誌中,則忽略該標誌。

width

定義放置引數值的欄位的最小寬度的整數。如果引數值的長度等於或大於 width,則列印該值,無需進行填充。如果該值小於 width,則將該值填充到 width 中指定的長度。

星號 (*) 表示寬度由引數列表中的相關引數指定,該寬度必須為整數值。

precision

從字串值的引數值中得到的最大字元數。例如,如果一個字串具有五個字元並且精度為 3,則只使用字串值的前三個字元。

對於整數值,precision 是指列印的最小位數。

星號 (*) 表示精度由引數列表中的相關引數指定,該精度必須為整數值。

{h | l} type

與字元型別 d、i、o、x、X 或 u 一起使用,用於建立 shortint (h) 值或 longint (l) 值。


型別規範 表示

d 或 i

有符號整數

o

無符號八進位制數

s

字串

u

無符號整數

x 或 X

無符號十六進位制數

請注意 這些型別規範基於最初為 C 標準庫中 printf 函式定義的規範。RAISERROR 訊息字串中使用的型別規範對映到 Transact-SQL 資料型別,而 printf 中使用的規範對映到 C 語言資料型別。當 Transact-SQL 不具有與關聯 C 資料型別類似的資料型別時,RAISERROR 不支援 printf 中使用的型別規範。例如,RAISERROR 不支援用於指標的 %p 規範,因為 Transact-SQL 不具有指標資料型別。

@local_variable

表示包含按照 msg_str 的方式格式化的字串的任何有效字串資料型別的變數。@local_variable 的資料型別必須為 char 或 varchar,或者必須能夠隱式轉換為這些資料型別。

severity

使用者定義的與該訊息關聯的嚴重級別。當使用 msg_id 引發使用 sp_addmessage 建立的使用者定義訊息時,RAISERROR 上指定的嚴重性將覆蓋 sp_addmessage 中指定的嚴重性。

任何使用者都可以指定 0 到 18 之間的嚴重級別。只有 sysadmin 固定伺服器角色成員或具有 ALTER TRACE 許可權的使用者才能指定 19 到 25 之間的嚴重級別。若要使用 19 到 25 之間的嚴重級別,必須選擇 WITH LOG 選項。


注意:
20 到 25 之間的嚴重級別被認為是致命的。如果遇到致命的嚴重級別,客戶端連線將在收到訊息後終止,並將錯誤記錄到錯誤日誌和應用程式日誌。


注意:
小於 0 的嚴重級別被解釋為級別為 0。大於 25 的嚴重級別被解釋為級別為 25。


state

介於 1 至 127 之間的任意整數。state 的負值預設為 1。值為 0 或大於 127 會生成錯誤。

如果在多個位置引發相同的使用者定義錯誤,則針對每個位置使用唯一的狀態號有助於找到引發錯誤的程式碼段。

argument

用於代替 msg_str 或對應於 msg_id 的訊息中的定義的變數的引數。可以有 0 個或多個替代引數,但是替代引數的總數不能超過 20 個。每個代替引數都可以是區域性變數或具有下列任一資料型別:tinyint、smallint、int、char、varchar、nchar、nvarchar、binary 或 varbinary。不支援其他資料型別。

option

錯誤的自定義選項,可以是下表中的任一值。


說明

LOG

在 Microsoft SQL Server 資料庫引擎 例項的錯誤日誌和應用程式日誌中記錄錯誤。記錄到錯誤日誌的錯誤目前被限定為最多 440 位元組。只有 sysadmin 固定伺服器角色成員或具有 ALTER TRACE 許可權的使用者才能指定 WITH LOG。

NOWAIT

將訊息立即傳送給客戶端。

SETERROR

將 @@ERROR 值和 ERROR_NUMBER 值設定為 msg_id 或 50000,不用考慮嚴重級別。


示例

A. 從 CATCH 塊返回錯誤訊息

下面的程式碼示例顯示如何在 TRY 塊中使用 RAISERROR 使執行跳至關聯的 CATCH 塊中。它還顯示如何使用 RAISERROR 返回有關呼叫 CATCH 塊的錯誤的資訊。


複製程式碼
BEGIN TRY
    -- RAISERROR with severity 11-19 will cause exeuction 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 目錄檢視中儲存的訊息。該訊息通過 sp_addmessage 系統儲存過程,以訊息號 50005 被新增到 sys.messages 目錄檢視中。


複製程式碼
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
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