RAISERROR の使用

RAISERROR は、SQL Server データベース エンジンにより生成されるシステム エラーや警告メッセージと同じ形式を使用して、アプリケーションにメッセージを返す場合に使用します。

RAISERROR では、次のいずれかを返すことができます。

  • sp_addmessage システム ストアド プロシージャを使用して作成されたユーザー定義エラー メッセージ。このようなメッセージは、sys.messages カタログ ビューで確認することができ、50,000 以上のメッセージ番号が付いています。

  • RAISERROR ステートメントで指定したメッセージ文字列。

また、RAISERROR により次の処理も行うことができます。

  • 特定のエラー番号、重大度、および状態を割り当てる。

  • エラーをデータベース エンジン エラー ログおよび Microsoft Windows アプリケーション ログに記録することを要求する。

  • C 言語の printf_s 関数のように、メッセージ テキストの引数の値を置き換える。

RAISERROR と PRINT のどちらを使用しても、アプリケーションに情報メッセージや警告メッセージを返すことができます。RAISERROR から返されるメッセージ テキストは、C 標準ライブラリの printf_s 関数と同様の文字列置き換え機能を使用して作成できますが、PRINT では、文字列または文字式しか返すことができません。重大度が 11 ~ 19 の RAISERROR が TRY…CATCH 構造の TRY ブロックで実行されると、これに関連付けられている CATCH ブロックに制御が移動します。CATCH ブロックを呼び出さずに RAISERROR を使用してメッセージを返すには、重大度を 10 以下に指定します。PRINT では、制御が CATCH ブロックに移動することはありません。

sys.messages で RAISERROR をユーザー定義メッセージの msg_id と共に使用した場合は、msg_id は SQL Server エラー番号またはネイティブ エラー コードとして返されます。msg_id ではなく msg_str と共に RAISERROR を使用した場合、返される SQL Server エラー番号およびネイティブ エラー番号は 50,000 になります。

RAISERROR を使用してユーザー定義エラー メッセージを返す場合は、そのエラーを参照する RAISERROR ごとに異なる状態番号を使用します。異なる状態番号を使用すると、エラー発生時にエラーを診断するのに役立ちます。

次の操作を行うには、RAISERROR を使用します。

  • Transact-SQL コードのトラブルシューティングに役立てる。

  • データの値を確認する。

  • 変数テキストを含むメッセージを返す。

  • 実行を TRY ブロックから関連付けられた CATCH ブロックに移動する。

  • CATCH ブロックから呼び出し元のバッチまたはアプリケーションにエラー情報を返す。

次に、アプリケーションに返すメッセージの中の引数を DB_ID() 関数と DB_NAME() 関数から取得した値で置き換える例を示します。

DECLARE @DBID INT;
SET @DBID = DB_ID();

DECLARE @DBNAME NVARCHAR(128);
SET @DBNAME = DB_NAME();

RAISERROR
    (N'The current database ID is:%d, the database name is: %s.',
    10, -- Severity.
    1, -- State.
    @DBID, -- First substitution argument.
    @DBNAME); -- Second substitution argument.
GO

次に、ユーザー定義メッセージを使用して上記の例と同じ情報を返す例を示します。

EXECUTE sp_dropmessage 50005;
GO
EXECUTE sp_addmessage 50005, -- Message id number.
    10, -- Severity.
    N'The current database ID is: %d, the database name is: %s.';
GO
DECLARE @DBID INT;
SET @DBID = DB_ID();

DECLARE @DBNAME NVARCHAR(128);
SET @DBNAME = DB_NAME();

RAISERROR (50005,
    10, -- Severity.
    1, -- State.
    @DBID, -- First substitution argument.
    @DBNAME); -- Second substitution argument.
GO

次のコード例では、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;