web-dev-qa-db-ja.com

ストアドプロシージャでSQLエラーを取得する方法

SQL Server 2005を使用しています。ほとんどの場合に機能するストアドプロシージャを作成しましたが、必要な処理を実行できないインスタンスが見つかりました。

現在、コードはこのようなことをしています

if @@error <> 0
  begin
   select @message_error = "There was a database error adding product "+ @product + " to product line
  end

どこ @message_errorは出力変数です。

だから、私はselect @@errorと番号を取得しますが、本当に欲しいのはSQLエラーだけです。

のようなものねえ、この列または何かにfk制約があるので、私はこれを行うことができませんでした。この記事はmsdnで見つかりました http://msdn.Microsoft.com/en-us/library/ms178592(v = sql.90).aspx

しかし、それはRAISERRORを使用してカスタム例外をスローすることだけを超えており、独自のエラーメッセージや例外を作成したくありません。 Management Studioからストアドプロシージャを実行して正確なSQLエラーを確認できますが、これはサイトのデータを照合して手動でそのように挿入するのは面倒です。

SQLエラーテキストを出力変数に取り込むにはどうすればよいですか?

11
Steve's a D

これが私が使用するストアドプロシージャテンプレートの一部です。

_/*  CREATE PROCEDURE...  */

DECLARE
  @ErrorMessage   varchar(2000)
 ,@ErrorSeverity  tinyint
 ,@ErrorState     tinyint

/*  Additional code  */

BEGIN TRY

/*  Your code here  */

END TRY

BEGIN CATCH
    SET @ErrorMessage  = ERROR_MESSAGE()
    SET @ErrorSeverity = ERROR_SEVERITY()
    SET @ErrorState    = ERROR_STATE()
    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)

    BREAK
END CATCH

/*  Further cleanup code  */
_

Try/Catchブロックはトリッキーになる可能性がありますが、@@ errorよりも完全です。さらに重要なのは、その中でさまざまなerror_xxx()関数を使用できることです。ここでは、適切なエラーメッセージを変数@ErrorMessageに格納するとともに、エラーを再発生させるのに十分な他のデータを格納しています。ここから、任意の数のオプションを使用できます。 @ErrorMessageを出力変数にしたり、特定のエラーをテストして処理したり、独自のエラーメッセージを作成したりできます(または既存のエラーメッセージをより明確に調整します-どれくらいの頻度でそれを実行したいかわからなくなることがあります)。他のオプションはそれらを表示します。

注意点:状況によっては、SQLは2つのエラーメッセージを連続してスローします...そしてerror_message()は最後のエラーメッセージのみをキャッチします。これは通常、「オブジェクトの作成に失敗しました」のようなメッセージを示します。最初のエラーメッセージで示される実際のエラー。ここで、独自のエラーメッセージを作成します。

19
Philip Kelley

一般的なTry/Catchを使用して、CATCHセクション内でエラーに関する詳細を作成できます。

DECLARE @DetailedErrorDesc VARCHAR(MAX)
BEGIN TRY

--tsql code goes here

END TRY
BEGIN CATCH

SELECT @DetailedErrorDesc =         
  CAST(ERROR_NUMBER() AS VARCHAR) + ' : '+
  CAST(ERROR_SEVERITY() AS VARCHAR) + ' : ' +
  CAST(ERROR_STATE() AS VARCHAR) + ' : ' +
  ERROR_PROCEDURE() + ' : ' +
  ERROR_MESSAGE() + ' : ' +
  CAST(ERROR_LINE() AS VARCHAR);

--Now you can decide what to do with the detailed error message....return it or log it etc

END CATCH
12
Myles J

try ... catchを使用し、catchブロックではERROR_MESSAGE()、ERROR_LINE()、ERROR_PROCEDURE()、ERROR_STATE()、ERROR_SEVERITY()、ERROR_NUMBER()関数を使用できます

3
Eduard Bader