16

我正在使用 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 存储的过程进行交互 - 所以过程很好。OraceleTypes.CURSOR和Spring的存储过程混用有错吗?我还能用什么?我也试过SqlReturnResultSet了,也没有用。

4

2 回答 2

6

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

在实践中,这意味着您必须使用JdbcTemplateand CallableStatementCallback,这意味着比您理想中的更多手动 JDBC 编码,但我还没有找到避免这种情况的方法。

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

于 2010-01-28T12:24:34.987 回答
4

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

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

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

于 2012-03-23T11:55:37.807 回答