内部错误:映像是集合映像,与Oracle一起使用的是ADT

问题描述

|| 我正在尝试使用spring-jdbc在oracle数据库调用存储的函数。 这是我尝试调用的存储函数
FUNCTION GET_RESOURCE_LIST RETURN RESOURCE_TAB;
接下来是resource_tab的定义
TYPE RESOURCE_TAB AS TABLE OF TRESOURCE;
接下来是tresource的定义
TYPE TRESOURCE AS OBJECT(
RESOURCE_ID NUMBER(10,0),RESOURCE_NAME VARCHAR2(100)
)
调用代码
final SimpleJdbcCall call = new SimpleJdbcCall(idmJdbcTemplate).withFunctionName(\"get_resource_list\").declareParameters(new sqlOutParameter(
        \"RETURN\",OracleTypes.STRUCT,\"RESOURCE_TAB\",new sqlReturnType() {

          @Override
          public Object getTypeValue(CallableStatement cs,int paramIndex,int sqlType,String typeName) throws sqlException {
            final Struct s = (Struct)cs.getobject(paramIndex);
            final Object[] attr = s.getAttributes();
            return attr[1];
          }             
        }));

call.compile();
final Collection<String> resources = call.executeFunction(Collection.class);
最后是我收到的堆栈跟踪:
org.springframework.jdbc.UncategorizedsqlException: CallableStatementCallback; uncategorized sqlException for sql [{? = call WVUID.IDM_REPO_MANUAL.GET_RESOURCE_LIST()}]; sql state [99999]; error code [17001]; Internal Error: Image is a collection image,expecting ADT; nested exception is java.sql.sqlException: Internal Error: Image is a collection image,expecting ADT
    at org.springframework.jdbc.support.AbstractFallbacksqlExceptionTranslator.translate(AbstractFallbacksqlExceptionTranslator.java:83)
    at org.springframework.jdbc.support.AbstractFallbacksqlExceptionTranslator.translate(AbstractFallbacksqlExceptionTranslator.java:80)
    at org.springframework.jdbc.support.AbstractFallbacksqlExceptionTranslator.translate(AbstractFallbacksqlExceptionTranslator.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:969)
    at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1003)
    Truncated. see log file for complete stacktrace

Caused By: java.sql.sqlException: Internal Error: Image is a collection image,expecting ADT
    at oracle.jdbc.driver.sqlStateMapping.newsqlException(sqlStateMapping.java:70)
    at oracle.jdbc.driver.DatabaseError.newsqlException(DatabaseError.java:133)
    at oracle.jdbc.driver.DatabaseError.throwsqlException(DatabaseError.java:199)
    at oracle.jdbc.driver.DatabaseError.throwsqlException(DatabaseError.java:263)
    at oracle.jdbc.driver.DatabaseError.throwsqlException(DatabaseError.java:271)
    Truncated. see log file for complete stacktrace
> 
    at org.springframework.jdbc.core.JdbcTemplate$5.doInCallableStatement(JdbcTemplate.java:1015)
    at org.springframework.jdbc.core.JdbcTemplate$5.doInCallableStatement(JdbcTemplate.java:1)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:953)
    ... 62 more
    

解决方法

我有同样的问题,我花了一天的时间来解决它。 考虑错误“图像是集合图像”,而不是
OracleTypes.STRUCT
必须是
OracleTypes.ARRAY
。 关于您的getTypeValue(...)方法,我不能说是对还是不对,但是我将展示如何解析结果集(也许是这样,请以其他方式写出来):
@Override
public Object getTypeValue(CallableStatement cs,int paramIndex,int sqlType,String typeName) throws SQLException {

    ARRAY struct = (ARRAY) cs.getObject(paramIndex);

    ResultSet rs = struct.getResultSet();

    while (rs.next()) {
        Object rowIndex = rs.getObject(1);
        oracle.sql.STRUCT row = (oracle.sql.STRUCT) rs.getObject(2);
        if (row != null) {
            Object[] cols = row.getAttributes();
            System.out.print(rowIndex + \": \");
            for (Object col : cols) {
                System.out.print(col + \" \");
            }
            System.out.println();
        }
    }

    return \"construct your data structure above and return here\";
}
另一种方法是
    @Override
public Object getTypeValue(CallableStatement cs,String typeName) throws SQLException {

    ARRAY array = (ARRAY) cs.getObject(paramIndex);

    Object[] rows = (Object[])array.getArray();

    for(Object row : rows){
        Object[] cols = ((oracle.sql.STRUCT)row).getAttributes();
        for (Object col : cols) {
            System.out.print(col + \" \");
        }
        System.out.println();

    }

    return \"construct your data structure above and return here\";
}
    ,问题在于输出参数的声明
final SimpleJdbcCall call = new SimpleJdbcCall(idmJdbcTemplate).withFunctionName(\"get_resource_list\").declareParameters(new SqlOutParameter(
    \"RETURN\",OracleTypes.STRUCT,\"RESOURCE_TAB\",new SqlReturnType() <etc>
返回类型(
TYPE RESOURCE_TAB AS TABLE OF TRESOURCE
)不是
OracleTypes.STRUCT
(为对象类型保留),而是an6ѭ。