Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does ODP.net close a ref cursor when the connection closes?

Tags:

c#

oracle

odp.net

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.

like image 318
Dave Baghdanov Avatar asked Dec 11 '08 00:12

Dave Baghdanov


People also ask

Do we need to close ref cursor in Oracle?

Best AnswerRefCursor does not need to explicitly closed.

What happens if we dont close the cursor in Oracle?

If you open such a cursor, it will stay open until you CLOSE it explicitly or you disconnect your Oracle session.

When should you close a cursor?

After all rows have been retrieved from the result set that is associated with a cursor, the cursor must be closed.

What happens when cursor is not closed?

Not closing a cursor will keep locks active that it holds on the rows where it is positioned.


1 Answers

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.

like image 172
Frans Bouma Avatar answered Oct 29 '22 01:10

Frans Bouma