views:

319

answers:

1

Pretty much what it says in the title, how the hell is this supposed to be done?

Basically i need to pass a null (empty?) ref cursor as an IN parameter to a stored procedure.

/** spring's PreparedStatementSetter#setValues(...) */
public void setValues(PreparedStatement ps) throws SQLException {
    CallableStatement cs = (CallableStatement) ps;
    cs.setString(1,"constant");
    //this is the IN param
    cs.setNull(2, OracleTypes.CURSOR);
    //this is the OUT param
    cs.registerOutParameter(3, OracleTypes.CURSOR);
}

And this fails with:

caused by: java.sql.SQLException: Unsupported feature: sqlType=-10
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
    at oracle.jdbc.driver.OraclePreparedStatement.setNullCritical(OraclePreparedStatement.java:4399)
    at oracle.jdbc.driver.OraclePreparedStatement.setNullInternal(OraclePreparedStatement.java:4161)
    at oracle.jdbc.driver.OracleCallableStatement.setNull(OracleCallableStatement.java:4472)

I'm at a loss here, tried several different ways to do this, but I couldn't find any examples about this and have no idea how to do it properly.

A: 

Hi deebo,

My java is a bit rusty, but you should be able to initialize your REF CURSOR variable in a PL/SQL block:

String statement = "DECLARE\n" +
                       "l_cursor SYS_REFCURSOR;\n" +
                   "BEGIN\n" +
                       "your_procedure(?, l_cursor, ?);\n" +
                   "END;"
CallableStatement cs = yourConnection.prepareCall(statement);
// bind first and last parameter
cs.setString(1,"constant");
cs.registerOutParameter(2, OracleTypes.CURSOR);
Vincent Malgrat
problem with this approach is that im using Spring Batch and a StoredProcedureItemReader, for which I just give a String parameter which is the procedure name, and a List of SqlParameter objects that create the CallableStatement (see: http://static.springsource.org/spring-batch/reference/html/readersAndWriters.html#StoredProcedureItemReader ), so unless something special exists in the sring core jdbc functionality, I'll be limited to using the CallableStatement reference directly to set the parameters
deebo
@deebo: In that case, you could create a PL/SQL procedure wrapper that only takes the two parameters and calls the stored procedure with a NULL argument.
Vincent Malgrat
The root of the problem was the Oracle JDBC driver, of which I had a version that did not support Cursors as IN parameters. I upgraded the driver and everything started working magically.
deebo