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。
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 ] ]
注意
若要檢視 SQL Server 2014 (12.x) 和更早版本的 Transact-SQL 語法,請參閱舊版文件。
引數
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 中轉換規格的欄位。 轉換規格具有這個格式:
% [[旗標] [寬度] [. 有效位數] [{h | l}]] 類型
可用於 msg_str 中的參數有:
旗標
決定替代值之間距與對齊的程式碼。
程式碼 | 前置詞或對齊 | 描述 |
---|---|---|
- (減) |
靠左對齊 | 給定欄位寬度內的引數值靠左對齊。 |
+ (加) |
符號前置詞 | 如果值是帶正負號型別,請在自變數值前面加上加號 (+ ) 或減號- 值。 |
0 (零) |
零填補 | 在輸出前加上 0,直到到達最小寬度為止。 當與減號 (- ) 出現時0 ,0 會忽略 。 |
# (數位) |
0x 或的 x 十六進位類型前置詞 X |
搭配o 、 x 或 格式使用時,數字符號 (# ) 旗標會分別以0 、 0x 或 X 0X 開頭任何非零值。 當 d 、 i 或 u 前面加上數字符號 (# ) 旗標時,會忽略 旗標。 |
' ' (空白) |
空間填補 | 如果輸出值帶正負號且為正值時,會在輸出值前加上空格。 當加上加號 (+ ) 旗標時,會忽略此填補。 |
寬度
定義引數值所在欄位最小寬度的整數。 如果引數值的長度等於或長於「寬度」 ,則列印出的值不帶填補。 如果值短於「寬度」 ,則會將值填補至「寬度」 中指定的長度。
星號 (*
) 表示寬度是由自變數清單中的相關聯自變數所指定,其必須是整數值。
有效位數
從字串值的引數值中取得的最大字元數。 例如,如果字串有五個字元而有效位數為 3,則只會使用字串值的前三個字元。
至於整數值,「有效位數」 是列印出的最少小數位數。
星號 (*
) 表示有效位數是由自變數清單中的相關聯自變數所指定,這必須是整數值。
{h | l} type
與字元類型 d
、i
、o
x
s
、X
、 或 u
搭配使用,並建立 shortint () 或 longint (h
l
) 值。
類型規格 | 表示 |
---|---|
d 或 i |
帶正負號的整數 |
o |
不帶正負號的八進位 |
s |
String |
u |
不帶正負號的整數 |
x 或 X |
不帶正負號的十六進位 |
這些類型規格會以原本為 C 標準程式庫中 printf
函數定義的規格為依據。 RAISERROR
訊息字串中使用的類型規格會對應到 Transact-SQL 資料類型,而 printf
中使用的規格會對應到 C 語言資料類型。 當 Transact-SQL 沒有類似相關聯 C 資料類型的數據類型時,不支援 中使用的printf
RAISERROR
類型規格。 例如, %p
中不支持 RAISERROR
指標的規格,因為 Transact-SQL 沒有指標數據類型。
若要將值轉換成 Transact-SQL bigint 資料類型,請指定 %I64d
。
@local_variable
任何有效字元數據類型的變數,其中包含格式與msg_str相同的字串。 @local_variable 必須是 char 或 varchar,或者能夠隱含轉換為這些資料類型。
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。 每個替代參數都可以是區域變數或任何以下的這些資料類型:tinyint、smallint、int、char、varchar、nchar、nvarchar、binary 或 varbinary。 不支援其他資料類型。
選項
錯誤的自訂選項,可以是下表的其中一個值。
值 | Description |
---|---|
LOG |
記錄錯誤記錄檔中的錯誤,以及 SQL Server 實例的應用程式記錄檔 資料庫引擎。 記錄在錯誤記錄檔中的錯誤目前最大限制為 440 位元組。 只有系統管理員固定伺服器角色的成員或具有ALTER TRACE 權限的使用者可以指定 WITH LOG 。適用於:SQL Server |
NOWAIT |
立即傳送訊息給用戶端。 適用於:SQL Server、Azure SQL 資料庫 和 Azure SQL 受控執行個體 |
SETERROR |
不論嚴重性層級為何,都將 @@ERROR 和 ERROR_NUMBER 值設定為 msg_id 或 50000。適用於:SQL Server、Azure SQL 資料庫 和 Azure SQL 受控執行個體 |
備註
由 RAISERROR
產生的錯誤,運作方式和由資料庫引擎程式碼所產生的錯誤相同。 RAISERROR
指定的值是由 ERROR_LINE
、ERROR_MESSAGE
、ERROR_NUMBER
、ERROR_PROCEDURE
、ERROR_SEVERITY
、ERROR_STATE
和 @@ERROR
系統函數所報告。 當 RAISERROR
在區塊中 TRY
執行嚴重性為 11 或更高版本時,它會將控制權傳輸至相關聯的 CATCH
區塊。 如果執行 RAISERROR
,就會將錯誤傳回給呼叫端:
- 在任何
TRY
區塊的範圍之外。 - 在
TRY
區塊中具備 10 或更低的嚴重性。 - 以會結束資料庫連接的 20 或更高的嚴重性執行。
CATCH
區塊可以使用 RAISERROR
來重新擲出錯誤,此錯誤可透過使用 ERROR_NUMBER
和 ERROR_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
相關內容
- SQL 資料庫函式是什麼?
- DECLARE @local_variable (Transact-SQL)
- PRINT (Transact-SQL)
- sp_addmessage (Transact-SQL)
- sp_dropmessage (Transact-SQL)
- sys.messages (Transact-SQL)
- xp_logevent (Transact-SQL)
- @@ERROR (Transact-SQL)
- ERROR_LINE (Transact-SQL)
- ERROR_MESSAGE (Transact-SQL)
- ERROR_NUMBER (Transact-SQL)
- ERROR_PROCEDURE (Transact-SQL)
- ERROR_SEVERITY (Transact-SQL)
- ERROR_STATE (Transact-SQL)
- TRY...CATCH (Transact-SQL)