11

私は 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 エラー テキストを出力変数に取得するにはどうすればよいですか?

4

3 に答える 3

21

私が使用するストアド プロシージャ テンプレートの一部を次に示します。

/*  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()最後のメッセージのみをキャッチします。これは通常、「オブジェクトの作成に失敗しました」のようなもので、実際のエラーは最初のエラー メッセージ。ここで、独自のエラー メッセージを作成します。

于 2012-11-30T15:05:22.680 に答える
12

一般的な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
于 2012-11-30T15:00:09.430 に答える
3

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

于 2012-11-30T15:01:06.353 に答える