1

接続と SqlReader を作成しましたが、両方を閉じるのを忘れていました。

SqlConnection conn = new SqlConnection("connection info");
conn.Open();

string sql = "SQL command HERE";
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader reader = cmd.ExecuteReader();

コードを再度実行しようとすると、常に次のエラーが表示されます。

System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

このリンクは、接続を適切に開いて閉じる方法を教えてくれましたが、まだ実行中の接続を閉じる方法については何も説明していませんでした。

私はPCをシャットダウンしようとしましたが、SQLサーバーでデータベースのオプションを調べてみました(役に立たないことがわかりました)...コードを変更して、接続とリーダーの両方を閉じるだけでした(コンパイルして実行しましたが、問題は残りました)コードを元に戻した後)。

この「ゴースト」接続を閉じるにはどうすればよいですか? 実行中のすべての接続を閉じる方法 (総当たり) はありますか?


[編集:]問題を本当に解決できませんでした。MultipleActiveResultSets=true回避策は、接続文字列に追加することでした

4

6 に答える 6

4

ゴースト オブジェクトにアクセスできないと思います。将来的には、using可能な場合はコンストラクトを使用してください。

using(SqlConnection conn = new SqlConnection("connection info"))
{
   conn.Open();

   string sql = "SQL command HERE";
   SqlCommand cmd = new SqlCommand(sql, con);
   SqlDataReader reader = cmd.ExecuteReader();
....
}
于 2012-04-17T19:32:04.900 に答える
3

using作成をステートメントでラップします。これにより、常に接続が閉じられることが保証されます。

using(SqlConnection conn = new SqlConnection("connection info"))
{
   // your code
}
于 2012-04-17T19:31:24.310 に答える
1

すべての回答を見ると、問題を回避する方法を教えてくれているようです。

私が間違っていなければ、クライアント (PC) とサーバー (SQL サーバー) の両方に接続が存在するということです。

サーバーへの接続は、電話での会話と考えてください。電話を切ることもできますが、接続が失われたことを電話が認識するまでに数秒かかります。私が電話を切ったのか、それとも話をやめたのか、そこに座っているかもしれません。あなたは本当に知りません。これは、接続が適切に閉じられていない場合にサーバーで発生することです。(古い固定電話では、電話をオフフックのままにして、回線を無期限に縛ることができました。)

コードで接続を閉じることにより、自分の接続を閉じる前に、接続の端を閉じるようにサーバーに効果的に伝えます。接続を閉じるのに失敗した場合、プログラムの終了時または再起動時に閉じられますが、サーバーは開いた接続でそこに座っている可能性があります。(そこに座って「彼は私に電話を切ったの?」と思っている人を考えてみてください)

私が間違っていなければ、あなたがやりたいことは、SQLサーバー側でそれを閉じることです。(彼らを「電話を切る」ようにさせる。)

再起動後、完全に閉じられます。サーバーで自動的にクリアする必要があります。

ただし、自分でやりたい場合は、次の情報を使用してコードの最後でサーバーでクリアできます: How do you kill all current connections to a SQL Server 2005 database?

はるかに簡単な方法は、ここで説明されているように SQL Server Management Studio で行うことです: http://www.mikebevers.be/blog/2009/07/kill-open-sql-processes-connections/

于 2012-04-17T20:01:18.960 に答える
1

これらの回答はすべて、問題を回避する方法を示していますが、問題の内容は説明していません。

SqlDataReader は前方のみのデータ アクセスを提供します。つまり、一度使用して完了したら、閉じて新しいものを作成する必要があります。詳細な説明については、このブログを参照してください。基本的に、DataReader を閉じないと、内部ではその接続とコマンド専用に開いたままになります。

他の人が述べているように、すべてのリソースを確実に閉じることをお勧めします。

using (SqlConnection connection = new SqlConnection("...")) {
    connection.Open();

    string sql = "SQL command HERE";

    using (SqlCommand cmd = new SqlCommand(sql, con))
    using (SqlDataReader reader = cmd.ExecuteReader()) {
            // do your stuff
    }
}
于 2012-04-17T19:38:24.030 に答える
0

正直なところ、接続を「閉じる」または「破棄」しても、接続文字列でプーリングを明示的に無効にしない限り、実際には消えません。ただし、これを行うことができます

http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.clearpool.aspx

于 2012-04-17T19:33:25.583 に答える
0

これは古い投稿であることはわかっています。これは誰の役にも立たないかもしれません。しかし、この質問で間違っていると思ったことを投稿する機会を見ました。

まず、conn という名前の SqlConnection を作成していますが、cmd という名前の SqlCommand では、接続として con を呼び出しています。これは問題です:

SqlConnection conn = new SqlConnection("connection info");
conn.Open();

string sql = "SQL command HERE";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader reader = cmd.ExecuteReader();

これが、エラーが発生する理由である可能性があります。

System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.

次に、完了後に conn を閉じるには、次を使用します。

conn.Close();

3 番目に、使用する SqlDataReader を閉じるには:

reader.Close();

しかし、SqlDataReader をリーダーに割り当てただけです。SqlDataReader を実際に開いたことはありません。それを開くには、次を使用します。

reader.Read();

または:

while (reader.Read())
{
    // Code
}

接続と SqlDataReader を開いたり閉じたりするときにこれらを初期化する適切な方法:

using (SqlConnection conn = new SqlConnection(sqlConnectionString))
{
    conn.Open();

    using (SqlCommand cmd = new SqlCommand())
    {
        cmd.Connection = conn;
        cmd.CommandText = "SELECT * FROM TableName;";

        SqlDataReader reader = cmd.ExecuteReader();

        reader.Read();

        if (reader.HasRows)
        {
            strCol1 = reader.GetValue(0).ToString();
        }

        reader.Close();
  }

  conn.Close();
}
于 2015-06-02T11:51:05.460 に答える