SQL Server異常コード処理の詳細解説


前言
SQL ServerはTRY...CATCH構造を用いてTSQL文のエラー処理を実現し、TRYコマンドは文の実行状況を監視し、TSQL文に異常が発生し、かつ重大レベル(Severity Level)が10より大きく、20未満であれば、CATCHコマンドは異常なエラーをキャッチする。

BEGIN TRY 
   { sql_statement | statement_block } 
END TRY 
BEGIN CATCH 
   [ { sql_statement | statement_block } ] 
END CATCH
データベース開発エンジニアは、1つ以上の語句をTRYコードブロックに書き込む必要があります。TRYコードブロックのコードが実行中にエラーが発生した場合、エラーが発生した点以降のコードは実行されず、プログラムの制御権はCATCHコードブロックに移行します。TRYコードブロックにエラーが発生していない場合、CATCHコードブロックは実行されず、プログラムの制御はEND CATCHの後のステートメントに移行する。
なお、CATCHコードブロックでキャプチャされた異常は呼び出しプログラムに戻りません。エラーメッセージを呼び出しプログラムに返す必要がある場合、CATCHコードブロックにTHROW(またはRAISERRORを使用する必要があります。使用を推奨しません)コマンド明示的にエラーを出す必要があります。
異常メッセージを取得する
TSQLでは、TRYとCATCHを用いて異常処理コードブロックを作成し、CATCHサブカルでは、以下の関数を用いて異常発生時の情報を取得することができる。

--           (LineNumber)
ERROR_LINE ( ) 
--     (ErrorNumber)
ERROR_NUMBER ( ) 
@@ERROR 
--      (ErrorMessage)
ERROR_MESSAGE ( ) 
--       SP Name
ERROR_PROCEDURE ( ) 
--        (Error Severity)
ERROR_SEVERITY ( ) 
--       (Error State)
ERROR_STATE()
SQL Serverから投げられたエラーは、通常はエラーコード(Error Number)、深刻レベル(Severity Level)、エラー状態(Error State)、エラーメッセージ(Error Message)などの情報を含む。
1,エラーコード
エラーコードは、変数@@ERRORと関数ERROR_からできます。NUMBER()は、エラーを一意に識別する前のステートメントに戻るためのエラーコードを取得する。
2,エラーの深刻なレベル
エラーの深刻なプログラム(Severity Level)は全部で24段階あり、SQL Severが問題に遭遇するタイプであることを示しています。Severity Levelはintタイプです。SEVERTY()は帰って、数値が大きいほど、問題が深刻になることを説明します。
エラーによるシステムへの影響プログラムによって、深刻なレベルを四つのグループに分けます。
  • -10:情報は、warning
  • と考えられます。
  • 11-16:エラーは、ユーザーコードによる
  • です。
  • 17-19:非常に深刻なエラーは、システム管理者によってのみ修復されます。
  • 20-24:致命的なエラーは、システム全体が正常に使用できなくなる可能性があります。

    17-19からは、エラーはユーザーによって修正されず、システム管理者によってのみ修復されます。

    20-24から、このレベルのエラーに遭遇することが少ないです。一旦遭遇したら、基本的にデータベースシステム全体が非常に深刻なエラーに遭遇したことを示します。

    3,エラー状態
    エラー状態(Error State)は、開発者が異常を引き起こす正確な位置を容易に識別することができるように、ユーザがカスタマイズしたコードです。
    4,エラーメッセージ
    エラーメッセージは、エラーに関する記述的なテキストであり、SQL Serverシステムによって予め定義されたエラー情報であっても良いし、THROWコマンドが投げ出したユーザ独自のテキストであっても良い。
    二、異常メッセージを投げかける
    SQL Server 2012および以降のバージョンでは、RAISERRORの代わりにThrowキーを使用して、異常をスローし、実行制御権をCatchコードブロックに移行する。
    THROW[error_]number,error_メッセージ、error_state;
    パラメータのコメント:
  • error_number:エラーコードは、intタイプで、値は5000より大きくなければなりません。2147483647より小さいです。これはユーザーがカスタマイズしたエラーコードです。
  • error_メッセージ:エラーメッセージ、タイプはnvarrhar(2048)
  • です。
  • state:エラーに関連するstateの一つで、タイプはtinyintで、取得範囲は0-255です。
  • 注意:THROW文の前の文はセミコロンでなければなりません。締めくくりをつける
    THROW文がカスタムの異常を出すために使用される場合、severty levelは常にデフォルトの16に設定されます。THROWがre-throwに使用されるとき、THROWはパラメータがなく、CATCHコードブロックの中にあり、CATCH捕捉の異常を再ドロップするだけで、severty level,state、エラーメッセージは元の異常と同じです。
    例1、カスタムの異常を投げる:
    
    BEGIN TRY 
      SELECT 1/0
    END TRY 
    BEGIN CATCH 
      ;THROW 51000, 'Divide by zero error encountered', 1;  
    END CATCH;
    SQL Serverが投げた異常メッセージは、カスタマイズされたエラーコードが51000で、深刻なレベル(Severity Level)が16で、エラー状態は1で、エラー行は5です。
    Msg 51000、Level 16、State 1、Line 5
    Divide byゼロerror encountered
    例2、重投げ異常、システムが検出したエラーをCatchコードブロックから投げ出す:
    
    BEGIN TRY 
      SELECT 1/0
    END TRY 
    BEGIN CATCH 
      ;THROW;  
    END CATCH;
    SQL Serverが投げた異常メッセージは、エラーコードは8134、深刻レベルは16、エラー状態は1、エラー行は2です。
    Msg 8134、Level 16、State 1、Line 2
    Divide byゼロerror encountered.
    三、TRY…CATCH構造の影響を受けないエラー
    TRY…CATCHは、深刻なレベルの11から19までのエラーのみをキャプチャし、深刻なレベルの捕獲は1−10、20−24のエラーです。
    session会システム管理者がKILL命令で殺すとTRY…CATCH構造は捕獲されません。
    四、異常を事務で処理する
    TRYコードブロックで生成されたエラーが現在のトランザクションの状態を無効にすると、このトランザクションは提出できないトランザクションです。提出してはいけないトランザクションは、read操作またはロールバック(ROLLBACK TRANSACTION)のみ実行できます。TSQL文を実行して書き込み操作を実行することはできません。この事務も提出できません。関数XACT_STATE()は-1に戻り、現在の事務は提出できない事務であることを示します。は、現在のトランザクションが提出可能であることを示します。データベース開発者はXACT_を通過する必要があります。STATE()は、事務に対して提出またはロールバックの操作を行います。
    例えば、異常処理は、下記のコードを参考にして、実際のアプリケーションで異常情報をデータテーブルに記録しても良いです。
    
    -- SET XACT_ABORT ON will render the transaction uncommittable when the constraint violation occurs.
    SET XACT_ABORT ON; 
     
    BEGIN TRY 
      BEGIN TRANSACTION; 
        -- A FOREIGN KEY constraint exists on this table. This statement will generate a constraint violation error.
        DELETE FROM Production.Product 
        WHERE ProductID = 980; 
      -- If the delete operation succeeds, commit the transaction. The CATCH block will not execute.
      COMMIT TRANSACTION; 
    END TRY 
    BEGIN CATCH 
      -- Test XACT_STATE for 0, 1, or -1. 
      -- If 1, the transaction is committable. 
      -- If -1, the transaction is uncommittable and should be rolled back.
      -- XACT_STATE = 0 means there is no transaction and a commit or rollback operation would generate an error.
     
      -- Test whether the transaction is uncommittable.
      IF (XACT_STATE()) = -1 
      BEGIN 
        --Logging Exception info, as the transaction is in an uncommittable state. Rolling back transaction.
        SELECT 
          ERROR_NUMBER() AS ErrorNumber, 
          ERROR_SEVERITY() AS ErrorSeverity, 
          ERROR_STATE() AS ErrorState, 
          ERROR_PROCEDURE() AS ErrorProcedure, 
          ERROR_LINE() AS ErrorLine, 
          ERROR_MESSAGE() AS ErrorMessage;  
        ROLLBACK TRANSACTION; 
      END; 
      -- Test whether the transaction is active and valid. 
      IF (XACT_STATE()) = 1 
      BEGIN 
        --'The transaction is committable. Committing transaction.' 
        COMMIT TRANSACTION;   
      END; 
    END CATCH;
    締め括りをつける
    ここでSQL Server異常コードの処理に関する記事を紹介します。SQLServer異常コードの処理内容については、以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。