Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SimpleJDBCall中的多个输出参数_Java_Spring_Spring Boot_Spring Jdbc - Fatal编程技术网

Java SimpleJDBCall中的多个输出参数

Java SimpleJDBCall中的多个输出参数,java,spring,spring-boot,spring-jdbc,Java,Spring,Spring Boot,Spring Jdbc,在JavaSpring引导框架中,尝试使用以下方法使用存储过程 jdbcTemplate.setDataSource(dataSource); SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate) .withSchemaName("abc")

在JavaSpring引导框架中,尝试使用以下方法使用存储过程

 jdbcTemplate.setDataSource(dataSource);

       SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate)
                                           .withSchemaName("abc")
                                           .withFunctionName("proname")
                                           .addDeclaredParameter(new
 SqlOutParameter("",""));
        Map<String, Object> map= new HashMap<>();
         map.put("a",a);
        map.put("b",b);
        map.put("c",c);
        map.put("d",d);

 SqlParameterSource in = new MapSqlParameterSource(map);
 Map<String, Object> out = simpleJdbcCall.execute(in);

正如在上面的代码中可以看到的,这个过程也有out参数,问题是我如何在简单的JDBC调用中提到多个out参数(注意多个)?

您可以按照以下教程从存储过程中接受多个
out
参数。这应该让您简要了解如何实现这一点:

  • 从上述文章中提取示例代码,下面是调用以执行存储过程的方式:

    SimpleJdbcCall jdbcCall = new SimpleJdbcCall(dataSource).withProcedureName("getRecord");
    SqlParameterSource in = new MapSqlParameterSource().addValue("in_id", id);
    Map<String, Object> out = jdbcCall.execute(in);
    

    希望这有帮助

    您可以使用SimpleJDBCall的方法,例如:


    我尝试了以下方法,效果很好:

    jdbcTemplate.execute((CallableStatementCreator) con -> {
            con = con.unwrap(OracleConnection.class);
            CallableStatement cs = con.prepareCall("{ ? = call usr.abc.proname(?,?,?,?,?,?,?) }");
            cs.registerOutParameter(1, OracleType.NUMBER);
            cs.setString(2, "a");
            cs.setString(3, "b");
            cs.setString(4, "c");
            cs.registerOutParameter(4, OracleType.NUMBER);
            cs.registerOutParameter(5, OracleType.NUMBER);
            cs.registerOutParameter(6, OracleType.VARCHAR);
            cs.registerOutParameter(7, OracleType.VARCHAR);
            return cs;
        }, (CallableStatementCallback<MyModel>) cs -> {
            cs.execute();
            return new MyModel(cs.getInt(1),
                               cs.getInt(4),
                               cs.getInt(5),
                               cs.getString(6),
                               cs.getString(7));
        });
    
    jdbcTemplate.execute((CallableStatementCreator)con->{
    con=con.unwrap(OracleConnection.class);
    CallableStatement cs=con.prepareCall(“{调用usr.abc.proname(?,,,,,,,,,,,,?)}”);
    cs.registerOutParameter(1,OracleType.NUMBER);
    cs.设置字符串(2,“a”);
    cs.设置字符串(3,“b”);
    cs.设置字符串(4,“c”);
    cs.registerOutParameter(4,OracleType.NUMBER);
    cs.registerOutParameter(5,OracleType.NUMBER);
    registerOutParameter(6,OracleType.VARCHAR);
    registerOutParameter(7,OracleType.VARCHAR);
    返回cs;
    },(CallableStatementCallback)cs->{
    cs.execute();
    返回新的MyModel(cs.getInt(1),
    政务司司长(4),
    政务司司长(五),
    cs.getString(6),
    cs.getString(7));
    });
    
    您可以这样做:

       SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate).withFunctionName("PRONAME")
    
                    .declareParameters(
                            new SqlParameter("z", Types.VARCHAR),
                            new SqlParameter("a", Types.VARCHAR),
                            new SqlParameter("b", Types.VARCHAR),
                            new SqlParameter("c", Types.VARCHAR),
                            new SqlInOutParameter("d", Types.NUMERIC),
                            new SqlOutParameter("e", Types.NUMERIC),
                            new SqlOutParameter("f", Types.VARCHAR),
                            new SqlOutParameter("g", Types.VARCHAR)
                    );
    
    
            Map<String, Object> result = call.execute("z", "a", "b", "c", 7);
            System.out.println(result);
    
    注意:在
    .declareParameters中
    参数顺序、类型和方向必须与db函数的参数匹配。

    您也可以使用(在中提供),它方便且类型安全。您的呼叫将如下所示:

    导入静态org.morejdbc.SqlTypes.*;
    导入静态org.morejdbc.NamedJdbcCall.call;
    导入org.morejdbc.*;
    ...
    私有JdbcTemplate JdbcTemplate;
    ...
    Out outD=Out.of(整数);
    Out outE=超出(长);
    Out oufF=Out.of(VARCHAR);
    Out Out=Out.of(VARCHAR);
    jdbcTemplate.execute(调用(“proname”)
    .in(“a”,a)
    .in(“b”,b)
    .in(“c”,c)
    .in(“z”,z)
    .inOut(“d”,d,outD)
    .out(“e”,outE)
    .出口(“f”,出口)
    .out(“g”,out));
    System.out.println(“d=“+outD.get()+”,e=“+outE.get()+”,f=“+outF.get()+”,g=“+outG.get());
    
    如果您有一个用于输入/输出参数的POJO,它可以更简洁,例如

    @lombok.Data//生成getter、setter和toString
    公共类产品数据{
    私人INTA;
    私人INTB;
    私人INTC;
    私人INTZ;
    私人int d;
    私人长e;
    私有字符串f;
    私有字符串g;
    }
    ...
    ProData数据=。。。;
    jdbcTemplate.execute(调用(“proname”)
    .in(“a”,data.getA())
    .in(“b”,data.getB())
    .in(“c”,data.getC())
    .in(“z”,data.getZ())
    .inOut(“d”,data.getD(),data::setD)
    .out(“e”,长,数据::setE)
    .out(“f”,VARCHAR,data::setF)
    .out(“g”,VARCHAR,data::setG));
    System.out.println(“数据:+数据);
    
    请注意,对于函数,调用不应该是
    call(“proname”)
    ,而是
    call(“proname”,VARCHAR)
    (您没有声明函数结果类型)。电话应该是这样的

    String result=jdbcTemplate.execute(调用(“proname”,VARCHAR)
    .in(“a”,data.getA())
    .in(“b”,data.getB())
    .in(“c”,data.getC())
    .in(“z”,data.getZ())
    .inOut(“d”,data.getD(),data::setD)
    .out(“e”,长,数据::setE)
    .out(“f”,VARCHAR,data::setF)
    .out(“g”,VARCHAR,data::setG));
    
    这是一个函数而不是一个过程OP询问如何使用多个输入输出参数调用db函数此答案仅显示如何使用单个参数调用过程我尝试了此方法并得到异常:
    索引处缺少输入或输出参数::1
    @Ulphat将所有输入参数添加为
    SqlParameter
    并将参数输出为
    SqlOutParameter
    OP询问的是SimpleJDBCall示例,而不是如何使用java.sql.Connection调用函数。而且,进行这种简单的调用也不需要拆开OracleConnection。我需要添加额外的行
    call.setAccessCallParameterMetaData(false)
    ,否则SQL将被翻译为
    {?=call proname()}
    ,即不使用任何参数。另外
    新的SqlOutParameter(“return”,Types.VARCHAR)
    应该是第一个参数,否则我会得到“PLS-00306:调用中参数的数目或类型错误”。但是,我的函数的类型被定义为
    %TYPE
    ,这可能导致了这种复杂性和对额外代码的需要。如果存储的proc OUT参数是oracle数据库中用户定义的自定义类型,如具有多个字段的“employee_t”或“Financials_t”类型,该怎么办?你是怎么把它映射到Java类的?我什么都试过了,但都没用
    .declareParameters(
                                new SqlParameter("in_id", Types.NUMERIC),
                                new SqlOutParameter("out_first_name", Types.VARCHAR),
                                new SqlOutParameter("out_last_name", Types.VARCHAR),
                                new SqlOutParameter("out_birth_date", Types.DATE)
                        );
    
    jdbcTemplate.execute((CallableStatementCreator) con -> {
            con = con.unwrap(OracleConnection.class);
            CallableStatement cs = con.prepareCall("{ ? = call usr.abc.proname(?,?,?,?,?,?,?) }");
            cs.registerOutParameter(1, OracleType.NUMBER);
            cs.setString(2, "a");
            cs.setString(3, "b");
            cs.setString(4, "c");
            cs.registerOutParameter(4, OracleType.NUMBER);
            cs.registerOutParameter(5, OracleType.NUMBER);
            cs.registerOutParameter(6, OracleType.VARCHAR);
            cs.registerOutParameter(7, OracleType.VARCHAR);
            return cs;
        }, (CallableStatementCallback<MyModel>) cs -> {
            cs.execute();
            return new MyModel(cs.getInt(1),
                               cs.getInt(4),
                               cs.getInt(5),
                               cs.getString(6),
                               cs.getString(7));
        });
    
       SimpleJdbcCall call = new SimpleJdbcCall(jdbcTemplate).withFunctionName("PRONAME")
    
                    .declareParameters(
                            new SqlParameter("z", Types.VARCHAR),
                            new SqlParameter("a", Types.VARCHAR),
                            new SqlParameter("b", Types.VARCHAR),
                            new SqlParameter("c", Types.VARCHAR),
                            new SqlInOutParameter("d", Types.NUMERIC),
                            new SqlOutParameter("e", Types.NUMERIC),
                            new SqlOutParameter("f", Types.VARCHAR),
                            new SqlOutParameter("g", Types.VARCHAR)
                    );
    
    
            Map<String, Object> result = call.execute("z", "a", "b", "c", 7);
            System.out.println(result);
    
    create function proname(z varchar2,
                                                a varchar2,
                                                b varchar2,
                                                c varchar2,
                                                d in out number,
                                                e out number,
                                                f out varchar2,
                                                g out varchar2)
                                                return varchar2 is
    begin
     d:=5;
     e:=6;
     f:='b';
     g:='c';  
    
    return 'test';
    end;