我试图调用一个接收多个字符串类型和一个对象表的存储过程,并返回一个对象表。这是我的类型:
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;
这是我的代码:
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();
}
}
当我运行它时,我明白了:
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)
我怀疑使用数组描述符的东西不是很正确,但它们都是正确构建的,所以也许它是我传入的null数组的返回值? Haven没有发现任何谷歌搜索显示出复杂的收藏品,所以我不知所措。
更新:在查看我在下面提到的网站上的代码之后,我写了这篇文章,它完美无缺。