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


问题内容

我正在使用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,但也没有用。


问题答案:

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

在实践中,这意味着您必须使用JdbcTemplateCallableStatementCallback,这意味着比您理想的方式要多得多的手动JDBC编码,但是我尚未找到避免这种情况的方法。

稍微来说,我相当怀疑JDBC规范的编写与Sybase(以及关联的SQL
Server)的工作方式非常一致,因为在JDBC中处理存储过程的方式非常适合那些人。系统(不适合Oracle)。