2009-05-28 18 views
0

データアクセスレイヤを扱う際に、エラー処理に関して確認するべきことは何ですか?例えば、データレイヤのエラー処理の訂正方法を修正してください

Public Function UserExists(ByVal userName As String) As DataTable 
     Dim dt As Object = Nothing 
     Dim arSqlParameters(0) As SqlParameter 
     arSqlParameters(0) = New SqlParameter("@UserName", SqlDbType.NVarChar, 50) 
     arSqlParameters(0).value = userName 
     dt = ABC.APP.DAL.DALHelper.ExecuteDatatable(ConnectionString, CommandType.StoredProcedure, "dbo.aspnet_sprGetUserByUsername", arSqlParameters) 
     Return dt 
    End Function 

..さんは、私がこの機能を持っていると仮定しましょう、これは非常に怠惰と危険なコーディングのように思えます。このような状況で予期せぬことをあなたのコードがうまく処理できるようにするにはどうしたらよいでしょうか?

私はvb.netを使い慣れていません。私が開発しているアプリでエラー処理が行われていないので、これはアドバイスを探すのに最適な場所だと思いました。事前に感謝:)

答えて

1

なぜdtをデータテーブルとして宣言していないのかわかりません - "dim dt as object = nothing"の動機は何ですか?

「dt = ABC.APP.DAL ....」の呼び出しは、実際にはうまくいかない場合があります。

  • ストアドプロシージャやパラメータ 名が間違っている:

    はそのラインでは、いくつかのエラーを持つことができます。これは、設計時に をキャッチしなければならない(しないことにより、 チェック機構を内蔵していますが、 コードを実行しようと 初めて)
  • エラーが格納 手順で発生します。ストアドプロシージャは、繰延名を使用する(例えば)場合は、実行時に エラーを引き起こす可能 解像度は、 は SPROCが呼び出された時点で存在しないオブジェクト。繰り返しますが、これはほとんどが です。
  • デッドロック。この場合、 バッチをキャッチして再送信する必要があります。 Hereのイントロやアプリケーション コード内のSQLエラーを処理上のリンク のセット。
  • 渡されたパラメータが 無効(長すぎる、間違ったデータ型、 など)です。これは の前にチェックしてください。の前にsprocを呼び出してください。
+0

"暗いdtをオブジェクト=無し"の背後にある動機を理解していない点に関しては、私は同意します。私はこれを開発サイクルの後期にやってきました。これは以前の開発者によってあらかじめ書かれたコードです。 – Chris

1

意見は、このようなトピックに乱暴に変わる可能性があるが、ここで私の感想です。あなたはこのエリアに関連する例外を処理しようとするだけです。これはあいまいな声明ですが、私が意味することは、ユーザーがdbの列よりも多くの文字を含む文字列を渡したかどうかです。あるいは、彼らは他のビジネスルールに違反しましたか?

私はではありません。データベースがダウンしていることを意味するcatchエラーがここにあります。これまでのコードでは、対処できるエラーをキャッチし、アプリケーションにはデータベースが必要です。問題をログに記録し、誰かに何かを通知するグローバル例外ハンドラを宣言し、ユーザーに「優雅な」終了を提示します。

各メソッドでデータベースに問題が発生しても、私は値を見ません。あなたは、あなたのデータ層の任意の部分を爆破するシナリオのためのコードを繰り返すだけです。つまり、このメソッドでdbエラー(またはその他の一般的なエラー)をキャッチすることを選択した場合、新しい例外をスローした場合には少なくともキャッチされた例外にinnerexceptionを設定します。または、あなたが望むものをログに記録し、次に「投げる」ではなく「投げる」ことができます。元のスタックトレースを保持します。

この場合もさまざまな考えがありますが、間違いなく明確な選択肢はありません。

1

オープンソースのORMソリューションのコード(SubsonicnHibernate)を参照してください。

私の限られた知識では、DALがそれほど大したことをすることができないため、接続に関するエラー、接続タイムアウトなどが渡されるべきだと思います。検証に関連するエラー(フィールド長、データ型など)などは、適切な詳細とともに返される必要があります。フィールド値を検証し、適切なエラーの詳細を返す検証メソッド(Subsonicに含まれています)を提供することができます。

0

私もこのに思考の多くを入れています。多くは特定のデータベースに依存します。したがって、SQL2000またはSQL2005 +を使用しているかどうかに応じて、ストアード・プロシージャーの戻りコード、RAISERRORまたはTRY-CATCHを実行します。ストアドプロシージャを使用して、開発者はより多くの情報を得るため

RAISERRORは、コードを返すことが好ましいです。最適なのは、50000以上の番号を選択して対応するメッセージを登録することですが、これはRAISERRORコールのテキストで伝えられる内容を伝えるだけの作業です。

戻りコードはソースコードストアドプロシージャの。 0の戻り値は、成功、失敗、0行、影響を受けたばかりの主キー、またはその日のストアドプロシージャライターの気まぐれに応じてリターンコードが設定されていない可能性があります。また、ADO.NETはExecuteNonQueryから行数を返します。したがって、一部の開発者はリターンコードをすばやく検出することが難しくなります。

アドホックソリューションは、例えば、も悪いです。

IF @@Error>0 
    SELECT 'Something bad happened' 

CLRストアドプロシージャを使用するオプションがある場合は、C#スタイルのエラー処理が有効になります。

したがって、RAISERRORをストアドプロシージャに追加してSqlExceptionをキャッチし、実際にユーザーデータエントリであることをユーザーに報告します。APIを悪用する開発者のものを記録し、接続や再試行を試みる可能性があります。実行タイムアウト

IF @Foo =42 
     BEGIN 
      RAISERROR ('Paramater @foo can''t be 42', 
       16, -- Severity = Misc. User Error. 
       1 -- State. == ad hoc way of finding line of code that raised error 
       ) ; 
      RETURN -1; --Just because some developers are looking for this by habit 
     END 
+1

RAISERRORを50000を超える数値で使用すると、別の問題が発生します。ユーザー定義のエラーコードはサーバー全体である(少なくとも2005年現在は2008年にチェックしなければならない)。特に、サーバー間でデータベースを移動し、独自のユーザー定義エラーを使用する他のデータベースを使用している場合は、些細ですが迷惑です。 –

関連する問題