例外がスローされた場合のストアドプロシージャからの出力値の取得方法

SqlServer Management Studioでは、ストアドプロシージャを実行するときに例外がスローされ、出力値も返されます。

私はC#.NETからその値を取得する方法を理解することはできません - 例外がスローされたときに実行が停止され、出力値が設定されません。

1
なぜ失敗したストアドプロシージャからの出力値が必要なのでしょうか?それは悪い習慣のように聞こえる。私は、例外をキャッチし、その場合はデフォルト値を使用することをお勧めします。あなたが本当に必要な場合はC#コードから提供してください。例外バブルを残してそれに応じてアプリケーションで処理してください。
追加された 著者 Ivaylo Slavov,
うーん、このブログの記事によると出力パラメータにエラーが発生してはいけませんが、テストしましたが、そのように見えます(この場合、 PROC FOO @I INT OUTPUT AS SET @ I = 10 SELECT 1/0
追加された 著者 Martin Smith,
上記のコメントに加えて、バッチ処理のエラーが発生しました。 SELECT CAST( 'FISH' AS INT)は未使用のままにします。
追加された 著者 Martin Smith,
@Ivaylo Slavov、例外がスローされた場合、出力パラメータを使用して追加情報を取得できます
追加された 著者 x2.,

3 答え

RAISERROR を使うことができます> - アプリケーションに指定された情報を返します。これは理想的な方法ではないかもしれません。これを実装するストアドプロシージャを制御できない場合は、遅すぎる可能性があります。

3
追加された
スローされるSqlExceptionのErrorsコレクションで追加情報を取得できます。さらに、上記の答えで示唆されているようにRAISERRORを使用することができ、ErrorsコレクションにはRAISERRORによってスローされた各エラーに関する情報が含まれます
追加された 著者 Ivaylo Slavov,

ストアドプロシージャとストアドプロシージャを実行しているコードの両方を制御できる場合は、OUTPUTストアドプロシージャパラメータを使用して呼び出し元にエラーコードを返すこともできます(つまり、@ErrorCode INT = 0 OUTPUT) 。

私の意見では、これにはエラーを引き起こすことに比べていくつかの利点があります。

1)例外処理は.NETフレームワークでは非常に高価です。必要なのは、入力したデータに何か問題があるか、データベースに競合があることをユーザーに伝えることです。エラーコードを戻すと、アプリケーションとサーバーのパフォーマンスは、スローするよりもはるかに小さい影響を与えます例外をキャッチします。

2)あなたの手続きが処理の中で十分に進んだ場合、他のパラメータを設定することができます。たとえば、レコードがロックされているユーザーに関する情報を含める必要がある場合は、この情報を別の出力パラメーターに含めて、コード内にエラーメッセージを作成することができます。

3)ストアドプロシージャでエンコードされたエラーメッセージを使用するよりも、メッセージの国際化やカスタマイズを簡単にサポートできます。

1
追加された
私はすでにこれをやっています。何が間違っているかに応じて、 @ bitErrorCondition1 または @ bitErrorCondition2 を設定して、自分の RAISERROR <コード>呼び出し。それはネットからうまく動作しますが、T-SQLバッチからsprocによって設定された出力変数を読み込もうとすると、 OUTPUT パラメータのいずれも設定されません。
追加された 著者 binki,
つまり、何も間違っているように誤って続行できないように、 RAISERROR を使いたいと思います。私は誤って静かな失敗をするのではなく、エラーを見たいと思っています。
追加された 著者 binki,

try catchブロックにクエリをカプセル化する場合、SQLServerメソッドを使用して例外データを取得できます。

BEGIN TRY
 --SQL Statements
END TRY

BEGIN CATCH
  --exception details

    SELECT ERROR_NUMBER()  
    SELECT ERROR_STATE()  
    SELECT ERROR_SEVERITY()  
    SELECT ERROR_LINE()  
    SELECT ERROR_PROCEDURE()  
    SELECT ERROR_MESSAGE()   

END CATCH

try catchブロックを実行していない場合。 SqlServerはエラーをログに記録し、次のコマンドを使用してt-sqlで読み取ることができます。

EXEC sys.xp_readerrorlog 1
1
追加された