我正在使用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是好的。将OraceleTypes.CURSOR
与Spring的存储过程混合是不对的?我还能用什么?我也尝试了SqlReturnResultSet
,但也没有用。
答案 0 :(得分:7)
这里的问题是Oracle执行存储过程的方式不符合JDBC。 Oracle的SP通过OUT参数或返回值作为游标返回结果集数据,并且必须专门处理它们。这意味着你不能使用任何假定符合JDBC的Spring的JDBC东西,你必须自己做。
实际上,这意味着你必须使用JdbcTemplate
和CallableStatementCallback
,这意味着比理想情况下更多的手动JDBC编码,但我还没有找到一种方法来避免此
稍微一点,我宁愿怀疑JDBC规范的编写是为了与Sybase(以及通过关联,SQL Server)的处理方式紧密相符,因为在JDBC中处理存储过程的方式非常好适合那些系统(并且不适合Oracle)。
答案 1 :(得分: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的自定义映射器。