javaoracle-databasejdbcsys-refcursor

Oracle JDBC Get SYS_REFCURSOR from procedure


I am using Oracle 12g and am trying to get a ResultSet from a SYS_REFCURSOR

I have a procedure with the following signature:

CREATE OR REPLACE PROCEDURE proc_search(user IN VARCHAR2, res OUT SYS_REFCURSOR)

This is the Java JDBC code I am using:

try {
    CallableStatement cstmt = con.prepareCall("exec proc_search(?, ?)");
    cstmt.setString(1, login);
    cstmt.registerOutParameter(2, Types.REF);
    cstmt.execute();
    ResultSet rs = (ResultSet)cstmt.getObject(2);

    while (rs.next()) {
        System.out.println(rs.getString(1));
    }
} catch (Exception e) {
    System.err.println(e);
    e.printStackTrace();
}

However, I'm getting the following error:

java.sql.SQLException: ORA-03115: unsupported network datatype or representation


Solution

  • First, getCursor method should be used for SYS_REFCURSOR instead of getObject

    Second, prepareCall should have BEGIN and END

    Code snippet

    try {
        CallableStatement cstmt = con.prepareCall("BEGIN proc_search(?, ?); END;");
        cstmt.setString(1, login);
        cstmt.registerOutParameter(2, OracleTypes.CURSOR); 
        cstmt.execute();
        ResultSet rs = ((OracleCallableStatement)cstmt).getCursor(2);
    
        while (rs.next()) {
            System.out.println(rs.getString("name"));
        }
    } catch (Exception e) {
        System.err.println(e);
        e.printStackTrace();
    }
    

    As a side note, it is imperative to have a finally block to close Connection, CallableStatement, ResultSet etc.

    finally {
        try {
            if (con != null)
                con.close();
    
            if (cstmt!= null)
                cstmt.close();
    
            if (rs!= null)
                rs.close();
    
        } catch (SQLException sqlexc) {
            sqlexc.printStackTrace();
        }
    }
    

    Update 1

    Using CallableStatement

        Connection conn = null;
        CallableStatement callableStatement = null;
        ResultSet rs = null;
    
        try {
            conn = getconn();
            callableStatement = conn.prepareCall("{call proc_search(?, ?)}");    
            callableStatement.setString(1, login);
            callableStatement.registerOutParameter(2, OracleTypes.CURSOR);
    
            callableStatement.executeUpdate();    
    
            rs = (ResultSet) callableStatement.getObject(2);    
            while (rs.next()) {
                String userid = rs.getString("name");
            }
    
        } catch (SQLException e) {
    
            System.out.println(e.getMessage());
            e.printStackTrace();
    
        } finally {
    
            if (rs != null) {
                rs.close();
            }
    
            if (callableStatement != null) {
                callableStatement.close();
            }
    
            if (conn != null) {
                conn.close();
            }
    
        }
    
        }