2017-05-29 22 views
1

私のコード閉じられていませんでした。のSystem.InvalidOperationException:接続が

private void button2_Click(object sender, EventArgs e) 
    { 
     sql.Open(); 

     string id = textBox1.Text; 
     string cadena = "DELETE FROM contacts WHERE id=" + id; 
     SqlCommand command = new SqlCommand(cadena, sql); 

     int cant; 
     cant = command.ExecuteNonQuery(); 

     if (cant == 1) 
     { 
      label4.Text = ""; 
      label5.Text = ""; 
      MessageBox.Show("Se ha eliminado"); 
     } 
     else 
      MessageBox.Show("No existe un artículo con el código ingresado"); 

     sql.Close(); 
     button2.Enabled = false; 
    } 

をしかし、既に密接な関係を宣言しています。

+1

悪い習慣は、あなたのコードに奇妙な形でぶつかる習慣があります。グローバル接続オブジェクトを保持しないでください。ローカルで使用するだけで、設定からロードされた接続文字列で作成し、それを使用して破棄します。 usingステートメントは検索するステートメントです。 – Steve

+0

コードにSQLインジェクション攻撃のベクトルがあり、クエリをパラメータ化します。 – t0mm13b

+0

(...)を使用している可能性がありますので、常に閉じます – urlreader

答えて

0

sql.Close();を確認してください。 それはelseブロックに含まれているようです。

int cant; 
    cant = command.ExecuteNonQuery(); 
    sql.Close(); //Move it here. 
    if (cant == 1) 
    { 
     label4.Text = ""; 
     label5.Text = ""; 
     MessageBox.Show("Se ha eliminado"); 
    } 
    else 
    { 
     MessageBox.Show("No existe un artículo con el código ingresado"); 
    } 
    button2.Enabled = false; 

接続を使用した後で接続を閉じる必要があります。

0

のは、最初からそれをやってみましょう、あまりにも多くの罪がコミットされています

//DONE: extract business logics, do not mix it with UI 
private bool DropContact(string id) { 
    //DONE: do not share single connection, but create when you want it 
    //DONE: wrap IDisposable into using 
    using (SqlConnection con = new SqlConnection(ConnectionStringHere)) { 
    con.Open(); 

    //DONE: make sql readable 
    //DONE: make sql parametrized 
    string cadena = 
     @"DELETE 
      FROM contacts 
      WHERE id = @prm_id"; 

    //DONE: wrap IDisposable into using 
    using (SqlCommand command = new SqlCommand(cadena, con)) { 
     //TODO: explict parameter type (int/string?) is a better then inplicit AddWithValue 
     command.Parameters.AddWithValue("@prm_id", id); 

     return command.ExecuteNonQuery() >= 1; 
    } 
    } 
} 
... 
private void button2_Click(object sender, EventArgs e) { 
    if (DropContact(textBox1.Text)) { 
    label4.Text = ""; 
    label5.Text = ""; 
    MessageBox.Show("Se ha eliminado"); 
    } 
    else { 
    MessageBox.Show("No existe un artículo con el código ingresado"); 
    } 

    button2.Enabled = false; 
} 
0

は、あなたの周りのsqlオブジェクトを共有しているように見えます。問題は、あなたが別の場所で接続を開いたが、決してそれを閉じなかったということだと思います。最終結果は、あなたがこの機能を取得することで、あなたはこの行を呼び出すときにそれが壊れる:

sql.Open(); 

はあなたのコードをチェックして、正しく接続を閉じていなかった場所を見つけます。

また、このような接続オブジェクトを共有するのではなく、毎回新しい接続オブジェクトを作成することをお勧めします。

0

コードに2つの問題があります。 1)接続を閉じる前に例外が発生することがあります。 usingステートメントを使用しないようにするには、キャッチする例外がサポートされているか、try-catch-finallyステートメントを使用して、finallyブロックでクローズ接続を使用できるため、非常に快適です。 2)接続ごとにSqlConnectionオブジェクトを初期化します(例を確認してください)。それはあなたが意味する問題を引き起こすかもしれないので、別々の操作の間にそれを共有しないでください。

using (SqlConnection con = new SqlConnection(connectionString)) 
{ 
    con.Open(); 
    using (SqlCommand command = new SqlCommand("your query", con)) 
    { 
    // output processing 
    } 
} 
0

再接続する前に接続状態を確認してください(以前と同じようにグローバルに使用する場合)。 (接続を公開したり、長時間開いてはいけません)

if (sql != null && sql.State == ConnectionState.Closed) 
    sql.Open(); 

接続を開こうとする前にこれを追加してください。あなたの戦略を強化する方がよいでしょう。

関連する問題