2011-08-13 12 views
1

私のプログラムでは、Oracleデータベースへの接続を開いて、カーソルを返すストアドプロシージャを介していくつかの行を読んでIDataReaderに入れ、接続を閉じて続ける。VB.NETでのOracle接続のクローズ

これで、接続を閉じる時点まですべて正常に動作します。私は接続がOracle用のTOAD経由でデータベースに開かれているのを見て、私がm_Connection.Closem_Connection.Disposeと言った後にデータベースが接続を維持しているように思った。

私はOracle.DataAccessを使用し、短時間の後に多くの接続があるというエラーが発生します。私はセッションをデバッグし、vbがclose()コマンドを実行し、それを実行するが、データベースは実行しないことを確認した。誰でもこの問題を解決する方法を知っていますか?

+0

接続文字列を投稿できますか? – Tridus

答えて

1

.Netでは、Try/Catch/Finallyブロックでデータベース接続をラップし、必ずFinallyセクションの接続を閉じる必要があります。これにはブロックUsingと略記されています。これは、クラスのメンバとして接続を維持することは、あなたがやっているように、ほとんどいつも間違った方法で行くことを意味します。 .Netは、クエリごとに新しい接続とコマンドオブジェクトを作成する方が良いように最適化されています。

DataReaderは少し特殊です。ブロックを使用してdatareaderを返すと、DataReaderが終了する前に接続を閉じることができます。 C#では、通常、イテレータで問題を回避します(yield return)。 VB.Netは、この構造のためにサポートしていないので、私はそうのように、代わりにAction(Of IDataRecord)を使用する場合があります。

Dim id As Integer 
If Integer.TryParse(IDTextBox.Text, id) Then 
    MyOracleQuery(id, _ 
     Function(r) 
      ''#... Do something with each "r" here 
     End Function _ 
    ) 
Else 
    ''# Complain to user about invalid ID 
End If 

注:

Public Sub MyOracleQuery(ByVal id As Integer, ByVal ProcessRecord As Action(Of IDataRecord)) 
    Dim sql As String = "SELECT <columns> FROM MyTable WHERE ID= @Id" 
    Using cn As New OracleConnection("connection string"), _ 
      cmd As New OracleCommand(sql, cn) 

     cmd.Parameters.Add("@Id", SqlDbTypes.Int).Value = id 
     cn.Open() 

     Using (rdr As IDataReader = cmd.ExecuteReader()) 
      While rdr.Read() 
       ProcessRecord(rdr) 
      End While 
     End Using 
    End Using 
End Sub 

あなたは今、あなたはそれを呼び出す、このコードに匿名メソッドを渡すことができますこのためには、Visual Studio 2010 /.Net 4にmutli-line匿名メソッドが必要です。古いプラットフォームでは、メソッドを宣言したいと思うでしょう。

+0

私はあなたの最初のコード構造を使いましたが、私が言ったように、接続は生き残り、私はstoredprocedure-classの処分関数の中でcn.closeとcn.dispose()を実行しました! – Husky110

+0

@Husky - ストアドプロシージャクラスにdispose関数がある場合は、usingブロックで囲む必要があります。 –

+0

は、使用ブロックにあります。そのため、私は接続が閉じないように私が混乱しているのです! – Husky110

関連する問題