I'm trying to call a stored procedure that receives several string types and one table of objects, and returns a table of objects. Here are my types:
create type recipientlist as object (
precedence varchar2(2), name varchar2(128), msgType varchar2(3));
create type recipientlist_t as TABLE of recipientlist;
create type recipientclient as object (pla varchar2(128), client varchar2(20));
create type recipientclientlist_t as table of recipientclient;
Here's my code:
import java.util.ArrayList;
import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
import java.sql.Types;
import oracle.jdbc.*;
import oracle.jdbc.oracore.OracleTypeCOLLECTION;
import oracle.jdbc.pool.OracleDataSource;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
class OadUtilities {
public static void main(String[] args) throws SQLException{
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:username/password@localhost:1521/myservicename");
Connection conn = ods.getConnection();
CallableStatement proc =
conn.prepareCall("{call extractAttributes(?,?,?,?,?,?)}");
ArrayDescriptor arrDesc1 =
ArrayDescriptor.createDescriptor("RECIPIENTLIST_T", conn);
<del>ArrayDescriptor arrDesc2 =
ArrayDescriptor.createDescriptor("RECIPIENTCLIENTLIST_T", conn);</del>
// instead of the ArrayDescriptor I use a StructDescriptor with ResultSetMetaData
StructDescriptor structDesc =
StructDescriptor.createDescriptor("RECIPIENTCLIENT", conn);
ResultSetMetaData metaData = structDesc.getMetaData();
String[] myRecipientData = {"TO","ADDRESS","LETTER"};
String[][] myRecipientDataArray = { myRecipientData };
Array myRecipientList = new ARRAY(arrDesc1, conn, myRecipientDataArray);
<del>String[] myClientData = new String[2];
String[][] myClientDataArray = { myClientData };
Array myClientList = new ARRAY(arrDesc2, conn, myClientDataArray);</del>
proc.setString(1, "X");
proc.setString(2, "ABC DEF GHI");
proc.setString(3, "JK LM NO");
proc.setString(4, "PQ");
proc.setArray(5, myRecipientList);
proc.registerOutParameter(6, Types.ARRAY);
<del>proc.setArray(6, myClientList);</del>
proc.registerOutParameter(6, Types.ARRAY, "RECIPIENTCLIENTLIST_T");
ResultSet rset = proc.executeQuery();
<del>while (rset.next()) {
System.out.println("ADDRESSEE = " + rset.getArray(1));
System.out.println("CLIENT = " + rset.getArray(2));
} </del>
// elements are java.sql.Structs
Object[] data = (Object[]) ((Array) proc.getObject(6)).getArray();
for(Object tmp : data) {
Struct row = (Struct) tmp;
// Attributes are index 1 based...
int idx = 1;
for(Object attribute : row.getAttributes()) {
System.out.println(metaData.getColumnName(idx) + " = " + attribute);
++idx;
}
System.out.println("---");
}
// close the result set, the statement and connect
rset.close();
conn.close();
}
}
When I run it, I get this:
Exception in thread "main" java.sql.SQLException: ORA-03115: unsupported network datatype or representation
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:202)
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1005)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449)
at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3493)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1491)
at oadUtilities.OadUtilities.main(OadUtilities.java:50)
I suspect that something is not quite right with the array descriptors, but they all built correctly, so maybe it's the null array I'm passing in for the return? Haven't found anything Googling that showed complex collections in and out, so I'm at a loss.
UPDATE: after looking at the code at the site I mention below, I wrote this up and it works perfectly.