spring jdbctemplate 不返回带有隐式游标的存储过程

问题描述 投票:0回答:1

我有一个像下面这样的SP

create or replace mystoredprocedure(userid VARCHAR, batchno VARCHAR) as 
begin
 open cursor c1 for 
    select * from table A;
 dbms_sql.return_result(c1);
open cursor c2 for 
    select * from table B;
 dbms_sql.return_result(c2);
end;

使用 1 - 这会抛出“无法对 pl/sql 语句执行 fetch :next

1. jdbctemplate. query ("call mystoredprocedure", new Object[]{userid,batchno}, new int[]{Types.VARCHAR,Types.VARCHAR},new BeanPropertyRowMapper<>(SampleBO.class));

使用 2 -这不会给出结果

2. 
MyStoredProcedure extends StoredProcedure
MyStoredProcedure mysp = new MyStoredProcedure(jdbcTemplate,"mystoredprocedure");
mysp.compile();
mysp.setParameters( sqlParameter array);
Map result = mysp.execute(param1,param2)

使用 3 - 结果大小为空白

3. SimpleJdbcCall jdbccall  =  new SimpleJdbcCall(jdbctemplate).withProcedureName("mystoredprocedure").withoutprocedurecolumnmetadataaccess().withnamebinding().returningresultset("rs1,new BeanPropertyRowMapper.newInstance(MyBean1.class)).returningresultset("rs2,new BeanPropertyRowMapper.newInstance(MyBean2.class).addDeclaredParameter(new SqlParameter("userid",Types.VARCHAR)).addDeclaredParameter(new SqlParameter("batchno",Types.VARCHAR));

Map actualParams = new HashMap();
actualParams.add("userid","20025");
actualParams.add("batchno","BATCH20025");

Map<String,object> results = jdbccall.execute(actualParams);

还有其他方法来获取两个结果集吗?

请帮忙

oracle stored-procedures spring-jdbc jdbctemplate
1个回答
0
投票

据我记得,Oracle 在第二个结果集上返回 ORA-17283 时存在一个问题,使调用者相信没有更多游标返回,解决方案是针对该特定错误调用 stmt.getMoreResults() ,并且然后重试 getResultSet()。然而,如果这在 JDBC 中很容易实现,那么如果您不想切换到 JDBC 来进行该调用,则可能必须从 Spring 中继承一些子类。

这里是匿名块解决方案的示例:

public interface ResultSetProcessor {
    void process(ResultSet rs) throws SQLException;

    void notifyResultSetChange();
}

/**
 * When using ORACLE 12c feature to return the cursor: DBMS_SQL.RETURN_RESULT(cur)
 * 
 * @param sqlConn
 * @param sqlBlock
 * @param processor
 * @throws SQLException
 */

public static void anonymousBlockCursorOra12(final Connection sqlConn, final String sqlBlock,
        final ResultSetProcessor processor) throws SQLException {
    try (final PreparedStatement s = sqlConn.prepareStatement(sqlBlock)) {
        boolean result = s.execute();

        do {
            // Check for more results if not already done in this iteration
            if (result) {
                try (final ResultSet rs = s.getResultSet()) {
                    while (rs.next()) {
                        processor.process(rs);
                    }
                }
                catch (final SQLException e) {
                    // Ignore ORA-17283: No resultset available
                    if (e.getErrorCode() != 17283) {
                        LOGGER.error(UtilsOJDBCLogPrefix.SQL_EXCEPTION, e);
                        throw e;
                    }
                }
                result = s.getMoreResults();
                if (result) {
                    processor.notifyResultSetChange();
                }
            }
            else if (s.getUpdateCount() == -1) {
                // Ignore -1 value if there is one more result!
                result = s.getMoreResults();
            }
        }
        while (result);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.