Spring的存储过程-从过程返回的结果总是空的

Posted

技术标签:

【中文标题】Spring的存储过程-从过程返回的结果总是空的【英文标题】:Spring's Stored Procedure - results coming back from procedure always empty 【发布时间】:2011-01-10 09:29:36 【问题描述】:

我正在使用 Spring 的 JdbcTemplate 和 StoredProcedure 类。我无法让存储过程类为我工作。

我在 oracle 数据库上有一个存储过程。它的签名是

CREATE OR REPLACE PROCEDURE PRC_GET_USERS_BY_SECTION
(user_cursor OUT Pkg_Types.cursor_type
 , section_option_in IN Varchar2
 , section_in IN Varchar2) AS ....

在哪里

TYPE cursor_type IS REF CURSOR;

我创建了以下存储过程类来从 oracle 过程中获取信息

    private class MyStoredProcedure extends StoredProcedure 

    public MyStoredProcedure(JdbcTemplate argJdbcTemplate) 
    
        super(argJdbcTemplate, "PRC_GET_USERS_BY_SECTION");
        declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR));
        declareParameter(new SqlParameter("input1", Types.VARCHAR));
        declareParameter(new SqlParameter("input2", Types.VARCHAR));
        compile();          
    


    public Map<String, Object> execute() 

        Map<String, Object> inParams = new HashMap<String, Object>();
        inParams.put("input1", "BG");
        inParams.put("input2", "FE");
        Map output = execute(inParams);
        return output;
    

我在我的一个 DAO 类中的一个方法中调用它

    public List<String> getUserListFromProcedure() throws BatchManagerException

    MyStoredProcedure sp = new MyStoredProcedure( this.jdbcTemplate );
    Map<String, Object> result = new HashMap<String, Object>();
    try
    
        result = sp.execute();
    

    catch( DataAccessException dae) 
    

    
    System.out.println(result.size());
    return null;

但地图的大小始终为 0,因此没有任何返回。我知道数据库中有符合我输入条件的行。我也有代码工作,它使用java.sql.CallableStatement 与 oracle 存储的 proc 交互 - 所以 proc 很好。将OraceleTypes.CURSOR 与 Spring 的存储过程混用有错吗?我还能用什么?我也试过SqlReturnResultSet,但也没有用。

【问题讨论】:

【参考方案1】:

这里的问题是 Oracle 执行存储过程的方式不符合 JDBC。 Oracle 的 SP 通过 OUT 参数返回结果集数据或返回值为游标的值,必须对其进行特殊处理。这意味着您不能使用任何假定符合 JDBC 的 Spring JDBC 东西,您必须自己做。

实际上,这意味着您必须使用 JdbcTemplateCallableStatementCallback,这意味着手动 JDBC 编码比您理想中的要多得多,但我还没有找到避免这种情况的方法。

顺便说一句,我相当怀疑 JDBC 规范的编写是为了与 Sybase(以及,通过关联,SQL Server)的处理方式非常一致,因为在 JDBC 中处理存储过程的方式非常好适合那些系统(不适合 Oracle 的)。

【讨论】:

您好,感谢您的反馈。我用我的 Oracle 存储过程得到了这个。问题出在我声明的输出参数上。以下作品 declareParameter( new SqlOutParameter( "output", oracle.jdbc.OracleTypes.CURSOR, new RowMapper() public String mapRow(ResultSet argResults, int argRowNum ) throws SQLException return argResults.getString(1); ) ) ;这现在对我有用。谢谢 您应该已经回答了自己的问题并将其选为接受的答案。无论如何,感谢您发布。【参考方案2】:

如果您在声明作为 CURSOR 的 outparam 时不传递 RowMapper,问题很简单。 Spring 将返回 即空光标。

 declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR)); - returns empty 
 declareParameter(new SqlOutParameter("output", OracleTypes.CURSOR, new ApplicationMapper()); - returns result

ApplicationMapper 是我实现 RowMapper 的自定义映射器。

【讨论】:

以上是关于Spring的存储过程-从过程返回的结果总是空的的主要内容,如果未能解决你的问题,请参考以下文章

使用 Spring JPA 调用存储过程

Spring data jpa 调用存储过程处理返回参数及结果集

Spring的存储过程,解析结果Map

调用另一个存储过程后从存储过程返回错误结果

Apache DbUtils:处理从存储过程返回的多个结果集

Oracle 存储过程返回结果集