Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.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 使用spring SimpleJDBCall调用Oracle函数_Java_Oracle_Procedure - Fatal编程技术网

Java 使用spring SimpleJDBCall调用Oracle函数

Java 使用spring SimpleJDBCall调用Oracle函数,java,oracle,procedure,Java,Oracle,Procedure,我正在努力与下面的代码,使其工作,搜索文档和论坛和结巴。 最后我决定向你求助。 我拥有的是包含类型、函数声明和函数体声明的包。 将来我想使用MYPACKAGE的同义词(这只是一个模拟-我的数据库中不会有package和types声明,而是使用dblink到外部数据库和Java代码来运行过程/函数,但现在我不允许访问此dblink),MYPACKAGE可以通过dblink访问: create public synonym dblink_MYPACKAGE for SOME_SCHEMA.MYPAC

我正在努力与下面的代码,使其工作,搜索文档和论坛和结巴。 最后我决定向你求助。 我拥有的是包含类型、函数声明和函数体声明的包。 将来我想使用MYPACKAGE的同义词(这只是一个模拟-我的数据库中不会有package和types声明,而是使用dblink到外部数据库和Java代码来运行过程/函数,但现在我不允许访问此dblink),MYPACKAGE可以通过dblink访问:

create public synonym dblink_MYPACKAGE for SOME_SCHEMA.MYPACKAGE@dblink_externalDB;
我将在Java代码中使用dblink_MYPACKAGE而不是MYPACKAGE。 (但这没关系吧?)外部数据库不是我们的,所以我们不能在那里更改任何内容

public class TestClassSpringBased {

private DataSource dataSource;

private SimpleJdbcCall jdbcCall;

@Override
public void testMe(Integer id) {

    int iid = 1;
    SqlParameterSource in = new MapSqlParameterSource().addValue("IN_1", iid);

    Map<String, Object> out = jdbcCall.execute(in);

}

public DataSource getDataSource() {
    return dataSource;
}

public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    jdbcTemplate.setResultsMapCaseInsensitive(true);

    this.jdbcCall = new SimpleJdbcCall(dataSource)
            .withCatalogName("MYPACKAGE")
            .withProcedureName("MYFUNCTION")
            .withReturnValue()
            .useInParameterNames("IN_1")
            .declareParameters(
                    new SqlInOutParameter("IN_1", OracleTypes.NUMBER),
                    new SqlInOutParameter("OUT_1", OracleTypes.STRUCT, "MYPACKAGE.CUSTOMELEMENTSTYPE",
                            new SqlReturnType() {
                                public Object getTypeValue(CallableStatement cs, int colIndx, int sqlType,
                                        String typeName) throws SQLException {

                                    return null; //just let it work, the I will think what to write here
                                }
                            }));

}

}





 create or replace 
 PACKAGE         MYPACKAGE IS 


   TYPE CUSTOMELEMENTSTYPE_R IS RECORD (
     C1 VARCHAR2(60),   
     C2    VARCHAR2(30)

  );

  TYPE CUSTOMELEMENTSTYPE IS TABLE OF CUSTOMELEMENTSTYPE_R 
  INDEX BY PLS_INTEGER;



 FUNCTION MYFUNCTION(
   IN_1 IN INTEGER, OUT_1 OUT CUSTOMELEMENTSTYPE )
 RETURN VARCHAR2;


   END;



create or replace 
 PACKAGE BODY MYPACKAGE  IS

   FUNCTION MYFUNCTION(
     IN_1 IN INTEGER, OUT_1 OUT CUSTOMELEMENTSTYPE )
    RETURN VARCHAR2  IS

  BEGIN

 SELECT *  BULK COLLECT INTO OUT_1
    FROM  SOME_TABLE;
   RETURN 'return param';
 END MYFUNCTION; 

  END MYPACKAGE ;
公共类TestClassSpringBased{
私有数据源;
私有SimpleJdbcCall;
@凌驾
公共void testMe(整数id){
int iid=1;
SqlParameterSource in=new-MapSqlParameterSource().addValue(“in_1”,iid);
Map out=jdbcCall.execute(in);
}
公共数据源getDataSource(){
返回数据源;
}
public void setDataSource(数据源数据源){
this.dataSource=数据源;
JdbcTemplate JdbcTemplate=新的JdbcTemplate(数据源);
setResultsMapCaseSensitive(true);
this.jdbcall=new SimpleJdbcCall(数据源)
.withCatalogName(“MYPACKAGE”)
.withProcedureName(“MYFUNCTION”)
.withReturnValue()
.useInParameterNames(“IN_1”)
.申报参数(
新的SqlInOutParameter(“IN_1”,OracleTypes.NUMBER),
新的SqlInOutParameter(“OUT_1”,OracleTypes.STRUCT,“MYPACKAGE.CUSTOMELEMENTSTYPE”,
新的SqlReturnType(){
公共对象getTypeValue(CallableStatement cs、int-colIndx、int-sqlType、,
字符串类型名)引发SQLException{
returnnull;//让它工作,我会考虑在这里写什么
}
}));
}
}
创建或替换
包我的包是
类型CUSTOMELEMENTSTYPE\u R为记录(
C1瓦查尔2(60),
C2瓦查尔2(30)
);
类型CUSTOMELEMENTSTYPE是CUSTOMELEMENTSTYPE\u R的表
通过PLS_整数进行索引;
函数MYFUNCTION(
IN_1 IN整数,OUT_1 OUT CUSTOMELEMENTSTYPE)
返回VARCHAR2;
结束;
创建或替换
包体我的包是
函数MYFUNCTION(
IN_1 IN整数,OUT_1 OUT CUSTOMELEMENTSTYPE)
返回VARCHAR2是
开始
选择*批量收集到输出1
从某张桌子上;
返回“返回参数”;
结束我的功能;
结束我的包;
错误是: org.springframework.jdbc.UncategorizedSQLException:CallableStatementCallback;SQL[{=调用MYPACKAGE.MYFUNCTION(?,)}]的未分类SQLException;SQL状态[99999];错误代码[17074];无效的名称模式:MYPACKAGE.CUSTOMELEMENTSTYPE;嵌套异常为java.sql.SQLException:无效的名称模式:MYPACKAGE.CUSTOMELEMENTSTYPE

问题是只有OUT参数,当我不传递参数并对另一个没有OUT参数的MYFUNCTION版本运行它时,相同的代码才能工作


我还尝试了OracleTypes.ARRAY(无效的名称模式)和OracleTypes.OTHER(原因:java.sql.SQLException:错误的列类型:1111)

似乎您使用了不正确的方法调用: 您的代码: .withProcedureName(“MYFUNCTION”)[…] 应该由 .withFunctionName[…]

下面是整个函数调用的一些简单示例:

JdbcTemplate jdbc = new JdbcTemplate(txManager.getDataSource());
    SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbc)
            .withCatalogName("p_adm_www")
            .withFunctionName("fn_usr_get_login_sequence")
            .declareParameters(new SqlOutParameter("RETURN", OracleTypes.NUMBER))
            .withoutProcedureColumnMetaDataAccess();
    jdbcCall.setAccessCallParameterMetaData(false);
    BigDecimal returnId = jdbcCall.executeFunction(BigDecimal.class, null);
    return returnId.longValue();

你能解决这个问题吗?就我记忆所及,我们在甲骨文上做过这样的事情。这是jdbc支持的一种类型nod,因此我们在Oracle上编写了一个包装函数/prodecure,调用原始函数,但新函数的参数类型正确。最初的一个是由dblink访问的,因为它不是我们的服务器,我们无法在那里更改任何内容。当然,您可以添加更多的IN或INOUT参数,这同样适用于我,没有任何问题。