2011-03-28 4 views
1

私は同じコマンドを実行するのに同じSqlConnectionSqlCommandオブジェクトを使用しようとしていました。異なるコマンドで複数回sqlコマンドを使用する

最初のものは重複をチェックし、2番目のものはユーザが入力したデータが重複していない場合にデータを挿入します。私は1つの接続を使用して、データベースへの旅行を保存しようとしていた

 using (SqlConnection conn = new SqlConnection(ConnStr)) 
     { 
      string Command = "SELECT CountryName FROM [Countries] WHERE CountryName = @Name"; 

      using (SqlCommand comm = new SqlCommand(Command, conn)) 
      { 
       comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 20); 
       comm.Parameters["@Name"].Value = Name; 

       comm.Parameters.Add("@IsVisible", System.Data.SqlDbType.Bit); 
       comm.Parameters["@IsVisible"].Value = IsVisible; 

       conn.Open(); 

       if (comm.ExecuteScalar() == null) 
       { 
         Command = "INSERT INTO [Countries] (CountryName, IsVisible) VALUES (@Name, @IsVisible);"; 
         comm.ExecuteNonQuery(); 
       } 
     } 

は、ここに私のコードのサンプルです。

問題がある:

最初のコマンドが実行されますが大丈夫 データベースに挿入 2番目のコマンドは動作しません(それはデシベルに すべてのレコードを追加しません)と私が に影響を受けた行を表示しようとしたとき は私に-1を与えました!

質問です:

が、これは ユニークな国を拘束する ために重複レコードをチェックするための理想的な方法ですか? 2番目の コマンドが実行されていないのはなぜですか?

+2

[接続プール](http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx)は、同じDB接続を使用してデータベースへのアクセスを保存する必要はありません。 (あなたが明示的にそれを無効にしている場合を除いて)ほぼ確実に使用されています。同じ接続を使用して2回実行すると、DBへの呼び出しが2回行われます。 – steinar

+0

アドバイスをありがとうございます。あなたの意見では、自分の状況でDbの負荷を軽減するための旅を救う方法があると思いますか? – lKashef

+0

ストアドプロシージャを使用する場合は、もっとも間違いありません。それはオプションですか? – steinar

答えて

2

変数Commandをinsertステートメントで書き直すときは、先に定義したCommandという名前の文字列を変更するだけです。 SqlCommandオブジェクト内に格納されているコマンドテキストは変更していません。

試行:

comm.CommandText = "へと挿入する[国](COUNTRYNAME、のisVisible)VALUES(@Name、@IsVisible);";

+0

それは単純だった..ありがとう=) – lKashef

3

string Commandの値を変更していますが、実際にはコマンド文字列をSqlCommand commに変更することはありません。

0

私の事私はあなたのselect文で挿入を区切ることをお勧め.. いろいろ書いよう:

private void Insert() 
    { 
     using (SqlConnection conn = new SqlConnection(ConnStr)) 
     {    
     string Command = "INSERT INTO [Countries] (CountryName, IsVisible) VALUES (@Name, @IsVisible)";  

     using (SqlCommand comm = new SqlCommand(Command, conn)) 
     { 
     comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 20); 
     comm.Parameters["@Name"].Value = Name; 
     comm.Parameters.Add("@IsVisible", System.Data.SqlDbType.Bit);     comm.Parameters["@IsVisible"].Value = IsVisible; 
     conn.Open(); 

     comm.ExecuteNonQuery(); 

     conn.Close(); 
     } 

} 

private void SelectInsert() 
{ 
     using (SqlConnection conn = new SqlConnection(ConnStr)) 
    {    
    string Command = "SELECT CountryName FROM [Countries] WHERE CountryName = @Name";    
    using (SqlCommand comm = new SqlCommand(Command, conn)) 
    { 
    comm.Parameters.Add("@Name", System.Data.SqlDbType.NVarChar, 20); 
    comm.Parameters["@Name"].Value = Name; 

    conn.Open(); 
    if (comm.ExecuteScalar() == null) 
    { 

      Insert(); //your save method 

    } 
    } 
} 

はあなたの最初の質問に答えるために

+0

あなたの時間に感謝:) ..しかしCommandTextを変えることはトリックでした! =) – lKashef

+0

:)ええと........ – Crimsonland

2

よろしく:いいえ、これはあります国名の一意性を保証する方法ではありません。データベースでは、CountryNameがプライマリキーになるようにCountriesテーブルを定義する必要があります(別の列をPKとして宣言し、CountryNameに一意制約を定義することもできます)。

重複した値を挿入しようとすると、例外がスローされ、適切に処理できます(既存のレコードを破棄して上書きし、別の値を入力するなど)。

あなたのメソッドで一意性をチェックすることは悪いと考えられます。これは、A)データベース自体に属するロジックをアプリケーションのコードに配置するためです。 B)潜在的な競合状態を導入し、他のアプリケーションやスレッドは、データベースの読み取りと書き込みの間に値を挿入します。

+0

+1 ..私はこれを答えとしてもいいと思っています。しかし、私の元々の質問は「なぜ私は期待される出力を得られないのですか」..しかし代わりに例外を処理するのが本当に正しいと思います。数字Bは私には少し流行だよ! =) – lKashef

+1

@IKashef:Bは比較的まれですが、多くの異なるスレッドが同時にデータベースにアクセスしている環境では、仕事を失うのに十分な頻度で頻繁に発生します。 :)私は長年にわたり他の人が書いた多くのアプリケーション/データベースを継承しており、開発者が一意性を保証するためにアプリケーションコードに依存していたあらゆる状況において、テーブルには多数の重複がありました。最終的には動作しないことが保証されているアプローチです。 – MusiGenesis

+0

あなたは私を救っただけです! ..私のアプリケーションは、複数の人に物事を追加することができるので、すべてのチームがデータを入力する必要がある時があります! ..おかげさまで、データベースが操作されたり、同時にアクセスされたときにこの問題を回避するための記事があれば、投稿してください.. + 1 – lKashef

関連する問題