4

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 レベルで追加情報を取得できないようです。したがって、この手法を使用してこのタスクを達成した人からの支援を探しています。Spring のドキュメントでは 3.2 でこれを推奨しているため、StoredProcedure を拡張するつもりはありません。

4

2 に答える 2