ODP.NETのDataReaderに限らず、DataReader(面倒なのでDRと略します)使い終わったらCloseしないとエライ事になるとの事でいつもなるべく早くCloseしているのがクセになっています。でも、人のプログラムを見ているとCloseしないでいるのもよく見ちゃいます。
カーソルを閉じないと言うことなので、DBに負担をかけると思うのですが、それで運用出来ているのだからたまたま影響が出ていないのでしょうか?それともどこかで破綻するのでしょうか?破綻するとしたらどこで破綻するのでしょうか?
DBの「最大オープンカーソル数」の設定値で破綻するんですね。
Oracleの場合「ORA-01000 最大オープン・カーソル数を超えました。」とエラーが吐かれます。
Oracle9i、10gではデフォルト300です。
ZAIKOFLGという列がある「TEST」テーブル(20行)のZAIKOFLGを加算して表示するだけのプログラムです。
Imports Oracle.DataAccess.Client Public Class Form1 Private CountOfExecute As Integer = 0 ''' <summary> ''' ''' </summary> ''' <param name="isClose"></param> ''' <remarks></remarks> Private Sub CloseTest( _ ByVal LoopCount As Integer, ByVal isClose As Boolean) Dim Cn As OracleConnection = Nothing Dim cmd As OracleCommand = Nothing Dim rd As OracleDataReader = Nothing Dim i As Integer Dim SumValue As Decimal = 0D Try CountOfExecute += 1 Cn = New OracleConnection( _ My.Settings.ConnectionString) cmd = New OracleCommand("", Cn) Cn.Open() cmd.CommandText = "select * from TEST" For i = 0 To LoopCount - 1 SumValue = 0D rd = cmd.ExecuteReader While rd.Read SumValue += CDec(rd.Item("ZAIKO")) End While If isClose Then rd.Close() End If Next ListBox1.Items.Add(CountOfExecute.ToString & _ "回目 : ZAIKO Total = " & SumValue.ToString) Catch ex As Oracle.DataAccess.Client.OracleException ListBox1.Items.Add("Oracle Error " & _ CountOfExecute.ToString & _ "回目 : LoopCount=" & i.ToString & _ " " & ex.Message) MessageBox.Show(ex.Message) Catch ex As Exception ListBox1.Items.Add(CountOfExecute.ToString & _ "回目 : LoopCount=" & i.ToString & " " & ex.Message) MessageBox.Show(ex.Message) Finally If Not IsNothing(rd) Then If Not rd.IsClosed Then rd.Close() End If rd.Dispose() End If If Not IsNothing(cmd) Then cmd.Dispose() End If If Not IsNothing(Cn) Then If Cn.State = ConnectionState.Open Then Cn.Close() End If Cn.Dispose() End If End Try End Sub Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Button1.Click 'クローズしないぜ CloseTest(CInt(TextBox1.Text), False) End Sub Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles Button2.Click 'クローズするか。 CloseTest(CInt(TextBox1.Text), True) End Sub End Class
見てもらうとわかりますが、1回目と3回目は「DataReaderをCloseするよー」ボタンを押した結果です。
それに対して2回目、4回目は「DataReaderをCloseしないよ」ボタンを押した結果です。
ものの見事にエラーが出ちゃいましたぁ....
必ずCloseしましょうね。
と言うわけで、プログラムにおける実験は一旦終了しますが、「なんでそうなるの?」とか、「どうしたらいいの?」などを追求したい方は、色んな所にテキストがありますが、@マークITのこの記事がわかりやすいので見てみてくださいね。
(2009.06.05) End of Text