2

我正在尝试使用 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
4

2 回答 2

4

我有同样的问题,我花了一天时间解决它。考虑错误“图像是集合图像”,而不是

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, int paramIndex,
        int sqlType, 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";
}
于 2012-02-07T21:25:31.840 回答
0

问题在于输出参数的声明

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) 不是 a OracleTypes.STRUCT(为对象类型保留)而是OracleTypes.ARRAY.

于 2013-08-22T07:02:34.387 回答