2

いくつかの列を持つテーブルがあり、テーブルに重複がないことを確認するために、それらの列の3つに一意キーを設定しました。今、try / catchを使用して例外を飲み込み、重複をスローして更新を続行するforeachのが良い方法かどうか疑問に思っていました。

            try {
                sqlWrite.ExecuteNonQuery();
            } catch (SqlException sqlException) {
                if (!sqlException.ToString().Contains("Violation of UNIQUE KEY constraint")) {
                    MessageBox.Show("Error - " + Environment.NewLine + sqlException.ToString(), "Error SQL");
                }
            } catch (Exception exception) {
                MessageBox.Show("Error - " + Environment.NewLine + exception.ToString(), "Error SQL");
            }

または、挿入クエリ内でSELECTを実行して、行が存在するかどうか、および挿入をスキップするかどうかを確認する必要がありますか?データ検証の一部として例外を使用するのは良くないことを読みましたが、そのように使用されることが想定されています(たとえば、C#でファイルロックをチェックする方法はtry / catchで使用されることになっています)。

4

2 に答える 2

1

別の方法がある場合は、例外をスローしてキャッチしないでください。そして、あなたは今それを持っています。これを使って!

を使用してチェックおよび挿入する単一のSQLスクリプトまたはストアドプロシージャを作成できますIF NOT EXISTS(SELECT ...)。2つのクエリを作成するのは遅くなります。

于 2012-04-10T15:06:05.983 に答える
0

私は一般的に、主キーの関係は、データ検証のための絶対的な最後のフォールバック位置でなければならないと言います。プログラムがこれまでに到達し、一意キーに失敗する行を挿入しようとしている場合は、問題が発生しています。

最も単純なケースでは、それほど悪くはありません。他の依存関係なしで単一の行を挿入する場合、レコードを挿入してキャッチされたエラーをスローする方が、IDがすでに存在するかどうかを確認するためにselectを実行するよりも効率的である可能性があるという引数を作成できます。

ここで、一度に数十行または数百行を挿入/更新する可能性のあるトランザクションについて考えてみます。すべての行には一意のキーがあり、それらのいずれかがエラーをスローする可能性があります。次に、エラーがキャッチされたときに、DBはトランザクション全体をロールバックする必要があります。確かにC#にはトランザクションモードがありますが、DBをロールバックし、レコードの挿入時に更新された可能性のあるオブジェクトをロールバックする必要があります。それは非常に速く非常に複雑になります。

于 2012-04-10T15:09:00.707 に答える