脳梗塞には負けられない!

2008年12月26日に脳梗塞を発症。負けずに自転車と写真とBAND活動に熱中しているY.MATのブログ。

System.OutOfMemoryException の例外がスローされました。

2006-03-10 17:17:13 | IT技術的なこと
今のプロジェクトで「System.OutOfMemoryException の例外がスローされました。」なんてエラーが出ました。
あきらかにメモリ不足です。

あれ、しかし、メモリは潤沢にあったんではないか?
と思い調べれば実メモリ2Gもあり、仮想も足せば4Gもあります。
それでもメモリ不足とは、これいかに?

簡単な話でした。
Oracle のテーブルに数万件のデータがあり、それを全て取り込もうとしていたようです。
しかも、VisualBasic.NET の DataSet に。
実行したらあっという間に全てのメモリを使い切ります。

画面表示に使うような、多くて数十件くらいまでなら問題なくても、数万件てのはなしでしょう、って感じです。

PL/SQL ではやりたくないとの事で、VisualBasic.NET からの解決策を考えました。

CREATE OR REPLACE PACKAGE PAC_TEST AS
 TYPE refcur IS REF CURSOR;
 PROCEDURE refCursor(p_cur OUT refcur) ;
END PAC_TEST;
/
CREATE OR REPLACE PACKAGE BODY PAC_TEST AS
 PROCEDURE refCursor(p_cur OUT refcur)
 IS
 BEGIN
  OPEN p_cur FOR
   select * from OracleTable;
 END refCursol;
END PAC_TEST;
/

これを VisualBaseic.NET で ODP.NET を使って動かします。

Dim DBconn As OracleConnection = Nothing
Dim DBcomm As OracleCommand = Nothing
Dim DBreader As OracleDataReader
DBconn = New OracleConnection
DBconn.ConnectionString = " User Id=oraU;Password=oraP;Data source=oraH;"
DBconn.Open()
DBcomm = New OracleCommand
DBcomm.Connection = DBconn
DBcomm.CommandType = CommandType.StoredProcedure
DBcomm.CommandText = "PAC_TEST.refCursor"
DBreader = Dbcomm.ExecuteReader
Do While (DBreader.Read())
  Console.WriteLine("{0}:{1}", DBreader.GetValue(0), DBreader.GetValue(1))
Loop

これで解決。