Spring的存储过程 - 从过程返回的结果始终为空

aos*_*aos 15 java oracle stored-procedures jdbc spring-jdbc

我正在使用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 ....
Run Code Online (Sandbox Code Playgroud)

哪里

TYPE cursor_type IS REF CURSOR;
Run Code Online (Sandbox Code Playgroud)

我创建了以下存储过程类来从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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在我的一个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;
}
Run Code Online (Sandbox Code Playgroud)

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

ska*_*man 6

这里的问题是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)抛出SQLException {return argResults.getString(1);}})) ; 这对我来说很有用.谢谢 (8认同)
  • 您应该回答自己的问题并将其选为接受的答案.无论如何,谢谢你发帖. (2认同)