有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java SimpleJDBCall调用函数

我有一个名为GET_RISK_GROUP的oracle函数

当我尝试调用此函数时:

SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
                .withSchemaName("NEWIB")
                .withCatalogName("PKG_ONLINE_IB_PC_OPERATIONS")
                .withFunctionName("GET_RISK_GROUP");
        SqlParameterSource source = new MapSqlParameterSource().addValue("P_TAX_NUMBER", taxNumber);
        jdbcCall.executeFunction(String.class, source);

我得到一个例外:

2020-09-11 15:40:25.692 ERROR 1276 --- [nio-8698-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{? = call GET_RISK_GROUP()}]; SQL state [99999]; error code [17041]; Missing IN or OUT parameter at index:: 1; nested exception is java.sql.SQLException: Missing IN or OUT parameter at index:: 1] with root cause

找不到任何解决方案。有什么想法吗?由于这个问题,我将代码更改为:

jdbcTemplate.execute(
                con -> {
                    CallableStatement cs = con.prepareCall("{? = call NEWIB.PKG_ONLINE_IB_PC_OPERATIONS.GET_RISK_GROUP(?)}");
                    cs.registerOutParameter(1, Types.NVARCHAR); // or whatever type your function returns.
                    // Set your arguments
                    cs.setString(2, taxNumber);
                    return cs;
                },
                (CallableStatementCallback<String>) cs -> {
                    cs.execute();
                    String result = cs.getString(1);
                    return result; // Whatever is returned here is returned from the jdbcTemplate.execute method
                }
        );

这个很好用


共 (1) 个答案

  1. # 1 楼答案

    有了这方面的经验,我只能说只做一些标准的更改,然后再尝试,因为你说的代码在我的机器上工作。不记得WX了,但在其中一个问题中提到了jdbc驱动程序可以发挥作用

    我添加了withoutProcedureColumnMetaDataAccess这是因为SimpleJdbcCall喜欢经常查询列细节的元数据,并且为了避免将来在我们有更多这样的调用时出现性能问题,建议添加它

    对于函数调用,我们还需要注册(如何使用CallableStatement)或将其声明为第一个参数,该参数将作为函数的返回类型

    我希望下面能奏效

    SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
                    .withSchemaName("NEWIB")
                    .withCatalogName("PKG_ONLINE_IB_PC_OPERATIONS")
                    .withFunctionName("GET_RISK_GROUP")
                    .withoutProcedureColumnMetaDataAccess()
                    .declareParameters(new SqlOutParameter("return",Types.VARCHAR),
                                       new SqlParameter("p_tax_number", Types.VARCHAR));
            
    // add value to the paramaters                         
    SqlParameterSource parameterMap = new MapSqlParameterSource().addValue("p_tax_number", taxNumber);
            
    // call
    String result = jdbcCall.executeFunction(String.class, source);
    

    附言。 如果不起作用,你可以在问题中发布函数体,或者运行下面的查询并将结果粘贴到这里吗

    select object_name,argument_name,position,data_type,data_length,in_out 
    from   user_arguments
    where  OBJECT_NAME ='GET_RISK_GROUP' 
    and    Package_name='PKG_ONLINE_IB_PC_OPERATIONS'