Skip to Main Content
  • Questions
  • Passing a REF CURSOR from PLSQL to a java stored procedure as a java parameter

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Andrew.

Asked: November 26, 2007 - 9:07 am UTC

Last updated: December 10, 2007 - 10:24 am UTC

Version: 10.2.0.3

Viewed 10K+ times! This question is

You Asked

Tom.
I have seen numerous examples where java code can create a CallableStatement and retrieve a ref cursor as an OUT parameter or function result. You gave similar examples to the following in other threads on your site.

// Prepare a Callable Statement, to make a call to the PLSQL function
  // demo_refcursor.getRefCursor, and obtain the returned REFCURSOR
  CallableStatement stmt = 
      connection.prepareCall("{? = call demo_refcursor.getRefCursor }");
      
  // Set the Out Parameter type to be of type CURSOR
  stmt.registerOutParameter(1, OracleTypes.CURSOR);
  stmt.execute(); // Execute the statement

  // Cast the returned parameter, (defined as type, OracleTypes.CURSOR)
  // to a JDBC result-set. 
  resultSet = (ResultSet)stmt.getObject(1);



But is it at all possible to pass a ref cursor opened in plsql as a parameter to a java stored procedure? The main problem is: what is the java class of the input parameter for a ref cursor?
The stmt.registerOutputParameter(1, OracleTypes.cursor) command above must be setting up the data type mapping with the OracleTypes.cursor constant so that stmt.getObject(1) command can be cast as a ResultSet.

I am not a java expert so there could easily be something I am missing. Though, I've searched through the onion layers of java class docs and tried several attempts but none works thus far.

A few attempts:

public static String testRef (ResultSet cur)...
public static String testRef (oracle.jdbc.oracore.OracleType cur)...
public static String testRef (oracle.sql.STRUCT cur)...
public static String testRef (oracle.jdbc.oracore.OracleTypeREF cur)...

I find it odd that java must call plsql to get a ref cursor but that java can not seemingly accept a ref cursor parameter.

Thanks
Andrew


and Tom said...

it is currently only possible to RETURN a ref cursor from plsql

Rating

  (2 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

REF "curser"

Andrew Markiewicz, December 06, 2007 - 11:44 am UTC

Darn.
Thanks Tom.
Is there a technical reason for that? My understanding of a java stored procedure was that it is possible to obtain the same session as the plsql code was run in. If that is possible then the ref cursor opened by a plsql program could also be available to the java stored procedure.

That is, if my understanding of a ref cursor is correct. It is merely a pointer to the cursor that was opened. But that cursor is only accessible by that session. i.e. you can't pass a ref cursor to another session and expect to fetch from it since the memory for a session is not shared in that way. Please correct me if I'm wrong on that.

Andrew
Tom Kyte
December 10, 2007 - 10:24 am UTC

It just isn't. It is not a feature/function implemented in the database.


Got it

Andrew Markiewicz, December 20, 2007 - 5:57 pm UTC

Tom.
I figured out what I was doing wrong with passing a REF CURSOR to java. My java class was fine, but my plsql call specification had a problem which the compiler did not provide an error or warning for.

The main issue was that I provided the wrong java class in the plsql specification. I don't think the one I provided even exists (oracle.jdbc.driver.ResultSet). Just emphasizes one of the main learning curves with java... what class to use and where is it?



Here's the code:
import java.sql.*;

public class cursorInfo {

    public static String getColumnNames (ResultSet cur) 
        throws SQLException 
    {
        String ret = "";
        ResultSetMetaData curMeta = cur.getMetaData();
        int colCount = curMeta.getColumnCount();
        for (int i=1; i <= colCount; i++) {

            ret = ret + " " + curMeta.getColumnName(i);
        }
        
        return ret;
    }
}


First attempt:
sql->create or replace package csrInfo
  2  as
  3  
  4  
  5  function getColumnNames(rc in sys_refcursor)
  6  return varchar2
  7  as language java
  8  name 'cursorInfo.getColumnNames(oracle.jdbc.driver.ResultSet) return String';
  9  --name 'cursorInfo.getColumnNames(java.sql.ResultSet) return String';
 10  
 11  
 12  end;
 13  /

Package created.

Elapsed: 00:00:00.01
sql->show err
No errors.
sql->
sql->declare
  2      rc      sys_refcursor;
  3      cols    varchar2(100);
  4  begin
  5      open rc for
  6          select 1 xx, 2 rtr, 3 qwerty
  7            from dual;
  8  
  9      cols := csrInfo.getColumnNames(rc);
 10      dbms_output.put_line(cols);
 11  end;
 12  /
declare
*
ERROR at line 1:
ORA-29531: no method getColumnNames in class cursorInfo
ORA-06512: at "PROG.CSRINFO", line 5
ORA-06512: at line 9


Elapsed: 00:00:01.20


156th attempt:


sql->create or replace package csrInfo
  2  as
  3  
  4  
  5  function getColumnNames(rc in sys_refcursor)
  6  return varchar2
  7  as language java
  8  --name 'cursorInfo.getColumnNames(oracle.jdbc.driver.ResultSet) return String';
  9  name 'cursorInfo.getColumnNames(java.sql.ResultSet) return String';
 10  
 11  
 12  end;
 13  /

Package created.

Elapsed: 00:00:00.10
sql->show err
No errors.
sql->
sql->declare
  2      rc      sys_refcursor;
  3      cols    varchar2(100);
  4  begin
  5      open rc for
  6          select 1 xx, 2 rtr, 3 qwerty
  7            from dual;
  8  
  9      cols := csrInfo.getColumnNames(rc);
 10      dbms_output.put_line(cols);
 11  end;
 12  /
XX RTR QWERTY

PL/SQL procedure successfully completed.

Elapsed: 00:00:01.57



Andrew

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library