2009-02-25 15 views
4

一時テーブルを作成するときに、一時テーブルがすでに存在することを示すエラーメッセージが表示されます。一時テーブルはセッション固有のものなので、接続が正しく終了していないようです。私は、使用しているステートメントで持っているreturn文と何か関係があると思います。returnステートメントは、usingステートメントがデータベースへの接続を閉じるのを防ぐことができますか?

私は、次のコードを持っている:私は、同じ名前を持つ一時テーブルを作成するために、いくつかの場所で、コードのこの種を使用

using (IDbConnection connection = dbConnectionHandler.CreateConnection()) 
{ 
    connection.Open(); 
    CreateATempTable(); 
    PopulateTempTable(); 
    DataSet ds = CallStoredProcThatUsesTempTable(); 
    return ds; 
} 

を。

残念ながら、次のエラーが表示されます。There is already an object named '#MyTempTable' in the database

今、私は一時テーブルがセッションに固有であることを知っています。セッションが閉じられると、それは消えるはずです。

私はこれを引き起こす可能性があると考えている三つのこと...私はconnection.Closeを呼び出す必要が

  1. があります()私は私のusingステートメント
  2. I外にreturn文を配置する必要があり
  3. 返す前に作成したテンポラリテーブルを削除する必要があります

どれが誰か分かりますか?もし私が考えなかったことがあれば?

答えて

6

ここでは推測していますが、データベース接続プーリングの設定を確認してください。プーリングをオフにして、役立つかどうか確認してください。

通常、.NETライブラリレベルで接続を閉じる/ディスポジションすると、実際のデータベースサーバー接続は閉じられません。これはデータプロバイダ内の接続プールに返され、プログラムが同じパラメータと資格情報を持つ別の接続を要求すると再利用されます。オープンなトランザクションや多分いくつかの基本的なパラメータを除いて、私はデータベースセッションがプールに返される前に何らかの方法でリセットされるとは思わない。テンポラリテーブルのような、より高価なオブジェクトはそのまま残されます。

プールをオフにする(非常に非効率的)ことができます。または、作成しようとする前にテンポラリ・テーブルの存在を確認し、存在する場合はその内容を削除することもできます。または、接続を閉じる前に一時テーブルを削除することもできます。

+0

今のところ、接続が閉じられる前にテーブルを削除すると、テーブルが機能します。私はそれを手動で管理する必要があると感じていないので、実際にはその方法に満足していない...しかし、私はより良い方法を見つけるまで私は何かに移動します... – mezoid

+0

私はそのようなカップリングを作成し、一緒にドロップすると思う接続、テンポラリテーブルの作成、作業の実行、テンポラリテーブルのドロップ、接続の解放)は、あなたの状況に適したデザインです。作業中の部分に何らかのエラーがあった場合にテーブルを離れないように注意してください。 –

1

パワーサイクルが発生しないか、または他の重大な奇妙なコーナーケースが処理されない限り、呼び出されません。

あなたは証拠がオブジェクトをラップし、使用中のデータベース接続ライブラリの詳細を知らなくても

+3

電源を入れ直すと間違いなくオブジェクトが破棄されます;-) –

+1

しかし、呼び出されることはありませんので、ログイン/ログアウトが必要なリモートリソースがある場合は、代わりにタイムアウトを待たなければなりませんリモートリソースにタイムアウトがある場合。 – Quibblesome

+0

しかし、あなたは同じセッションに接続しないので、#TempTableが範囲外になり、競合は発生しません。 – MatBailie

0

にブレークポイントを入れたい場合は、私はそれが最初の二つのどちらだと思うだろう。 usingは、メソッドから戻ったときにそのようなリソースを簡単にクリーンアップするために特別に導入されました。 Javaのブロックtry...finallyなどと直接的に似ています。すなわち

は、returnブロックを残すとDispose方法は、そのような実装の正気を想定し、そのプロセスの一部としてCloseメソッドを呼び出す必要が接続上で呼び出されます。

ここで重要なポイントは「正常な実装」です。

1

使用ブロックは、フードの下でtry/catch/finallyブロックに変換されます。はい、使用ブロック内のリターンに関係なく処分されます。

3

私は、connection.Dispose()(したがってconnection.Close()も同様に)が呼び出されることを確信しています。

1)と2)を実行し、問題がまだ存在するかどうかを確認するだけで十分簡単に​​確認できます。解決策はおそらく3)であり、説明は接続プーリングです。

1

内部でを使用しているため、接続は常に呼び出されます。を使用すると、try/finallyブロックに配置されます。

また、接続プーリングを検討することもできます。 TransactionScopeでコードをラップしてみてください。ご質問にお答えするために

0

usingステートメントは、useブロック内にreturnステートメントがあっても、そのクラスがIDisposableである場合にオブジェクトを破棄します。

あなたの#temptableを保持するのは接続プーリングであり、手動でそのテーブルを削除することができます。

0

接続プーリングが原因です。トランザクションで何をしているのかを包み込み、最後にロールバックします。または、dsを入力した後に一時表を削除します。

関連する問題