tags:

views:

1657

answers:

2

I haven't been able to find this explicitly stated anywhere yet, but a bunch of examples I've found online follow what I've been doing.

I have a C# class which uses ODP.net to connect to an Oracle DB and run a procedure that's in a package.

My package has stored procedures which take a ref cursor output parameter. All the procedure does is open up the cursor for a particular select statement.

If I execute this procedure directly on the oracle db, then eventually I'll hit a max number of open cursors error.

So I was wondering if ODP.net does indeed close this cursor that was opened in my procedure?

I'm using the OracleDataApaper.Fill(DataSet) method.

eg.

DataSet ds = new DataSet();
OracleConnection conn = new OracleConnection(this.connStr);
OracleCommand com = new OracleCommand("MYPKG.MYQUERY", conn);
OracleDataAdapter adapter = new OracleDataAdapter(com);
conn.Open();
com.Parameters.Add("searchParam", OracleDbType.Varchar2).Value = "myName";
com.Parameters.Add("outCursor", OracleDbType.RefCursor, ParameterDirection.Output);
com.CommandType = CommandType.StoredProcedure;

adapter.Fill(ds);
conn.Close();




PROCEDURE GETALLEMAILS(searchParamIN VARCHAR2, outCursor OUT sys_refcursor) AS
  BEGIN
    open outCursor
      select 
        EAEMAL as Email
      from 
        EmailTable
      where 
        EmailName = searchParam;  
  END GETALLEMAILS;

I'm just afraid of leaving open cursors behind on the DB is all. If anyone can provide links to official documentation, that'd be great!


Updates:

Thanks for the input. I was calling

com.Dispose();
conn.Close();
conn.Dispose();

but left them out of my example.

I found this forum post, which states that the OracleDataAdapter.Fill(Dataset) method does release the ref cursor after the Fill() method has been executed.
http://www.frontoracle.com/oracle-archive/140/386140-close-ref-cursor.html

I wish the Oracle documentation was more explicit in describing this process though.

A: 

I'm not sure if you've stumbled onto this article, and it doesn't apply directly to your question, but it illustrates something I learned when working with ODP.Net: when in doubt, always close (connections) and dispose. Every method I write that uses an instance of ODP connections, commands, and/or cursors has a finally clause disposing everything.

AJ
+2  A: 

ODP.NET requires you to clean up things. So you:

  • have to dispose OracleParameter instances, as they contain unmanaged resources (!) and Odp.net doesn't do this
  • have to dispose OracleCommand objects, as they too contain unmanaged resources and closing a connection doesn't close these
  • open cursors can't live without an open connection, though in odp.net nothing gets cleaned up after a connection closes (or gets disposed), so you have to clean up these too (and before the connection closes of course).

I.o.w.: clean up what you create.

It can be the OracleDataAdapter already does this for you, but that's unclear (and the odp.net docs don't say this, so you've to check the (unreadable) code with reflector to make sure. Though rule of thumb with odp.net: to avoid memory leaks, always call dispose, on everything in the order: parameter, cursor, command, transaction, connection.

Frans Bouma