I ran into the problem of restricting an open cursor using the following code. The open cursor limit on oracle db is set to about 1000. The following code seems to hold on cursors, even if I have everything in the using statement (I think) that requires it. (Note, I do not need to read anything from outRefCursor2)
Am I missing using or any other cleanup using ODP.net?
The exception occurs sequentially at iteration 596.
static List<Thing> GetDetailsForItems(List<string> items) { DateTime start = DateTime.UtcNow; var things = new List<Thing>(); var spname = "SP_GET_THING_DETAILS"; var outRefCursorName1 = "p_ref_cursor1"; var outRefCursorName2 = "p_ref_cursor2"; // Create params var pInput1 = new OracleParameter("p_input1", OracleDbType.Varchar2, ParameterDirection.Input); pInput1.Value = ""; // Input 2 can be blank var pInput2 = new OracleParameter("p_input2", OracleDbType.Varchar2, ParameterDirection.Input); pInput2.Value = ""; var outRefCursor1 = new OracleParameter(outRefCursorName1, OracleDbType.RefCursor, ParameterDirection.Output); var outRefCursor2 = new OracleParameter(outRefCursorName2, OracleDbType.RefCursor, ParameterDirection.Output); int count = 0; using (var conn = new OracleConnection(CONN_STR)) { conn.Open(); using (var cmd = conn.CreateCommand()) { cmd.Parameters.Add(pInput1); cmd.Parameters.Add(pInput2); cmd.Parameters.Add(outRefCursor1); cmd.Parameters.Add(outRefCursor2); cmd.CommandText = spname; cmd.CommandType = CommandType.StoredProcedure; foreach (string value in items) { count++; cmd.Parameters[pInput1.ParameterName].Value = value; var execVal = cmd.ExecuteNonQuery(); using (var refCursor = (Types.OracleRefCursor) cmd.Parameters[outRefCursorName1].Value) { using (var reader = refCursor.GetDataReader()) { while (reader.Read()) { // read columns things.Add(reader["COLUMN_A"].ToString()); } } // close reader } // close cursor } // end foreach } // close command } // close connection int seconds = (DateTime.UtcNow - start).Seconds; Console.WriteLine("Finished in {0} seconds", seconds); return things; }
I use this snippet found on the Internet to monitor DB cursors. I can watch how cursors add up when I go through the code. And they just keep adding cmd.ExecuteNonQuery() lines. I never see a fall after closing any instruction.
select sum(a.value) total_cur, avg(a.value) avg_cur, max(a.value) max_cur, s.username, s.machine from v$sesstat a, v$statname b, v$session s where a.statistic
chris source share