我有一些使用 CallableStatement 工作的直接 JDBC 代码。我一直在尝试利用 DataSource、JdbcTemplate 和 SimpleJdbcCall 将其转换为 Spring。我基本上已经尝试了我能找到的 Spring 文档中的所有教程、示例和片段。通过调整,所有 Spring 解决方案都会产生相同的结果:
org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback; bad SQL grammar [{call UPCLSCH.P_GET_CLASS_SCHEDULE()}]; nested exception is java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'P_GET_CLASS_SCHEDULE'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
这是正在准备语句的日志部分:
2015-12-29 17:17:18 DEBUG SimpleJdbcCall:214 - Added declared parameter for [p_get_class_schedule]: p_classsched_ref_out
2015-12-29 17:17:18 DEBUG SimpleJdbcCall:214 - Added declared parameter for [p_get_class_schedule]: p_term
2015-12-29 17:17:18 DEBUG SimpleJdbcCall:214 - Added declared parameter for [p_get_class_schedule]: p_scauid
2015-12-29 17:17:18 DEBUG SimpleJdbcCall:214 - Added declared parameter for [p_get_class_schedule]: p_pidm
2015-12-29 17:17:18 DEBUG SimpleJdbcCall:336 - JdbcCall call not compiled before execution - invoking compile
2015-12-29 17:17:18 DEBUG DataSourceUtils:110 - Fetching JDBC Connection from DataSource
2015-12-29 17:17:18 DEBUG DriverManagerDataSource:162 - Creating new JDBC DriverManager Connection to [jdbc:oracle:thin:@umadmn.umt.edu:7895:ADMNRED]
2015-12-29 17:17:21 DEBUG CallMetaDataProviderFactory:123 - Using org.springframework.jdbc.core.metadata.OracleCallMetaDataProvider
2015-12-29 17:17:21 DEBUG CallMetaDataProvider:278 - Retrieving metadata for UPCLSCH/AP_ADMN/P_GET_CLASS_SCHEDULE
2015-12-29 17:17:22 DEBUG DataSourceUtils:332 - Returning JDBC Connection to DataSource
2015-12-29 17:17:22 DEBUG SimpleJdbcCall:304 - Compiled stored procedure. Call string is [{call UPCLSCH.P_GET_CLASS_SCHEDULE()}]
2015-12-29 17:17:22 DEBUG SimpleJdbcCall:282 - SqlCall for procedure [p_get_class_schedule] compiled
2015-12-29 17:17:22 DEBUG SimpleJdbcCall:385 - The following parameters are used for call {call UPCLSCH.P_GET_CLASS_SCHEDULE()} with: {}
2015-12-29 17:17:22 DEBUG JdbcTemplate:937 - Calling stored procedure [{call UPCLSCH.P_GET_CLASS_SCHEDULE()}]
2015-12-29 17:17:22 DEBUG DataSourceUtils:110 - Fetching JDBC Connection from DataSource
2015-12-29 17:17:22 DEBUG DriverManagerDataSource:162 - Creating new JDBC DriverManager Connection to [jdbc:oracle:thin:@xxxxx.xxx.xxx:7895:PRIVATE]
2015-12-29 17:17:24 DEBUG DataSourceUtils:332 - Returning JDBC Connection to DataSource
这是可以工作的直接 JDBC 代码(无连接详细信息):
private static List<ScheduledClass> callOracleStoredProcCURSORParameter() throws SQLException {
Connection connection = null;
CallableStatement callableStatement = null;
ResultSet rs = null;
List<ScheduledClass> scheduledClassList = new ArrayList<ScheduledClass>();
String getDBUSERCursorSql = "{call upclsch.p_get_class_schedule (?, ?, ?, ?)}";
try {
connection = getApConnection();
callableStatement = connection.prepareCall(getDBUSERCursorSql);
callableStatement.registerOutParameter("p_classsched_ref_out", OracleTypes.CURSOR);
callableStatement.setString("p_term", "201570"); //term code
callableStatement.setString("p_scauid", "rs213498");
callableStatement.setString("p_pidm", null);
callableStatement.executeUpdate();
rs = (ResultSet) callableStatement.getObject("p_classsched_ref_out");
while (rs.next()) {
ScheduledClass sc = new ScheduledClass();
sc.setCourseNumber(rs.getString("subject_code") + rs.getString("course_number"));
sc.setCourseTitle(rs.getString("course_title"));
scheduledClassList.add(sc);
}
} catch (SQLException e) {
e.printStackTrace();
}
return scheduledClassList;
}
这是我的非工作 Spring 代码(注意注释掉的部分在将“in”传递给 sjc.execute() 时会产生相同的结果):
public void setDataSource(DataSource dataSource){
this.jt = new JdbcTemplate(dataSource);
jt.setResultsMapCaseInsensitive(true);
sjc = new SimpleJdbcCall(jt)
.withCatalogName("upclsch")
.withProcedureName("p_get_class_schedule");
}
public Map<String, Object> execute(String termCode, String netId){
sjc.useInParameterNames("p_term", "p_scauid", "p_pidm")
.declareParameters(new SqlOutParameter("p_classsched_ref_out", OracleTypes.CURSOR),
new SqlParameter("p_term", OracleTypes.VARCHAR),
new SqlParameter("p_scauid", OracleTypes.VARCHAR),
new SqlParameter("p_pidm", OracleTypes.VARCHAR));
// SqlParameterSource in = new MapSqlParameterSource()
// .addValue("p_scauid", netId, OracleTypes.VARCHAR)
// .addValue("p_term", termCode, OracleTypes.VARCHAR)
// .addValue("p_classsched_ref_out", OracleTypes.CURSOR);
Map<String, Object> results = sjc.execute();
return results;
}
我似乎无法在 TRACE 或 DEBUG 级别获得任何其他信息,以查看我的参数是否排序不正确。因此,我正在寻求使用此技术完成此任务的任何人的帮助。我不打算扩展 StoredProcedure,因为 Spring 文档建议将其用于 3.2。