來源http://msdn.microsoft.com/zh-cn/library/ms177497.aspx
RAISERROR 用於將與 SQL Server 數據庫引擎生成的系統錯誤或警告消息使用相同格式的消息返回到應用程序中。
RAISERROR 還可以返回:
- 已通過 sp_addmessage 系統存儲過程創建的用戶定義的錯誤消息。這些消息的消息號大於 50000;可在 sys.messages 目錄視圖中查看這些消息。
- 在 RAISERROR 語句中指定的消息字符串。
RAISERROR 還可以:
- 分配特定的錯誤號、嚴重度和狀態。
- 請求將錯誤記錄到數據庫引擎錯誤日誌和 Microsoft Windows 應用程序日誌中。
- 將參數值代入消息正文中,這與 C 語言中的 printf_s 函數非常相似。
RAISERROR 和 PRINT 都可以用來將信息性消息或警告消息返回到某個應用程序中。RAISERROR 返回的消息正文可以使用類似 C 標準庫中的 printf_s 函數的字符串替換功能來生成,然而 PRINT 只能返回字符串或字符表達式。如果在 TRY...CATCH 構造的 TRY 塊中執行的 RAISERROR 嚴重度介於 11 到 19 之間,會導致將控制傳遞到關聯的 CATCH 塊。如果指定 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 塊返回到進行調用的批處理或應用程序。
生成錯誤消息並啓動會話的錯誤處理。RAISERROR 可以引用 sys.messages 目錄視圖中存儲的用戶定義消息,也可以動態建立消息。該消息作爲服務器錯誤消息返回到調用應用程序,或返回到 TRY…CATCH 構造的關聯 CATCH 塊。
- 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 將引發一個錯誤號爲 50000 的錯誤消息。
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、s、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 不具有指針數據類型。 注意: 若要將值轉換爲 Transact-SQL bigint 數據類型,請指定 %I64d。
- @ 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
-
0 到 255 的整數。負值或大於 255 的值會生成錯誤。
如果在多個位置引發相同的用戶定義錯誤,則針對每個位置使用唯一的狀態號有助於找到引發錯誤的代碼段。
- 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,不用考慮嚴重級別。
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
A. 從 CATCH 塊返回錯誤消息
以下代碼示例顯示如何在 TRY
塊中使用 RAISERROR
使執行跳至關聯的 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 目錄視圖中存儲的消息。該消息通過 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