2011-08-13 55 views
1

在我的程序中,我得到了多個地方,我打開了一個到Oracle數據庫的連接,通過存儲過程讀取了一些行,它返回一個遊標,將它們放入一個IDataReader中,關閉連接並繼續。在VB.NET中關閉Oracle連接

現在一切正常,直到關閉連接點。我觀察了通過TOAD for Oracle向數據庫開放的連接,我發現數據庫似乎在我說m_Connection.Closem_Connection.Dispose後保持連接。

我使用Oracle.DataAccess並在短時間後出現錯誤,表示存在多個連接。我打開了會話並確認,該vb執行close()命令並執行它,但數據庫不是。任何人有一個想法如何解決這個問題?

+0

你可以發佈你的連接字符串嗎? – Tridus

回答

1

在.Net中,您需要將數據庫連接包裝在Try/Catch/Finally塊中,並且始終關閉Finally部分中的連接。有一個簡稱爲Using塊。這意味着保持一個連接作爲一個類的成員(正如你似乎正在做的)幾乎總是錯誤的方式去做。 .Net已經過優化,因此最好爲每個查詢創建一個新的連接和命令對象。

數據讀取器有點特別:如果您將數據讀取器從使用塊中退出,則可以在DataReader完成之前關閉連接。在C#中,我通常用迭代器解決問題(yield return)。由於VB.Net缺少這種結構的支持,我可能會使用一個Action(Of IDataRecord)代替,就像這樣:

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 

現在,您可以通過匿名方法這段代碼時,你怎麼稱呼它:

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 

注這需要Visual Studio 2010 /.Net 4用於多線匿名方法。對於較老的平臺,您需要聲明該方法。

+0

我這樣做就像你的第一個代碼構造使用,但正如我所說的,連接保持活着,我執行cn.close和cn.dispose()正確的處理我的storedprocedure類的功能! – Husky110

+0

@Husky - 如果你的存儲過程類有一個dispose函數,它也必須被封裝在一個using塊中。 –

+0

是在使用塊,這就是爲什麼我很困惑,連接不會關閉! – Husky110