As Mike said, you cannot directly refer to a row type in a JDBC call, since row types are valid only in PL / SQL, and all types used by the driver must be defined at the SQL level.
You can define your own type of SQL object that obscures your table structure (which you will need to remember in order to update if the table has been modified), and a wrapper procedure that accepts this type and converts it into a call to your real procedure. This is a double based demo, since I don't know your real table structure:
create type ni_imsi_rowtype as object (dummy varchar2(1))
Then, on the Java side, you can populate and send this as STRUCT:
// Object array containing the values corresponding to your row type Object[] rowObj = { "X" }; // Struct based on the SQL type you created StructDescriptor structDesc = StructDescriptor.createDescriptor("NI_IMSI_ROWTYPE", conn); STRUCT rowStruct = new STRUCT(structDesc, conn, rowObj); // Call wrapper function instead of real one cs = conn.prepareCall("{ call ni_imsi_pkg.get_curx_wrapper(?,?) }"); // Pass the struct defined earlier cs.setObject(1, rowStruct); cs.registerOutParameter(2, OracleTypes.CURSOR); // and other arguments for your real calll
If you cannot change your real package, you can create a new one for the wrapper or a simple procedure; or you can even make the conversion in an anonymous block, although this makes Java code more complex:
cs = (OracleCallableStatement) conn.prepareCall( "declare l_typ ni_imsi_rowtype; l_buf dual%rowtype; " + "begin l_typ := ?; l_buf.dummy := l_typ.dummy; ni_imsi_pkg.get_curx(l_buf, ?); " + "end;" );
... still binds the same structure, so the SQL type is still required. Only the statement is changed, but now it can call the original procedure without a shell.
source share