我正在使用JDBC CallableStatement调用带有命名参数的过程。
程序:
create or replace PROCEDURE VIST_COMP(I_STUDY IN VARCHAR2, I_STARTDATE IN VARCHAR2, I_ENDDATE IN VARCHAR2, I_EMPLOYEE IN VARCHAR2, I_EMPLOYEE_OPTIONAL IN NUMBER, I_SPONSOR IN VARCHAR2, I_SPONSOR_OPTIONAL IN NUMBER, p_rc OUT SYS_REFCURSOR)
AS
o_cursor SYS_REFCURSOR;
sqlqry clob;
BEGIN
//procedure code
END VIST_COMP;
Java代码:
String runSP = "call VIST_COMP(:protocols,:alertStartDate,:alertEndDate,:employee,:employeeOptional,:sponsor,:sponsorOptional, :out_cursor)";
try (Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:localhost:389/oracle", "username", "password");
CallableStatement callableStatement = conn.prepareCall(runSP)) {
callableStatement.setString("protocols","12345");
callableStatement.setString("alertStartDate", "03-Apr-2019");
callableStatement.setString("alertEndDate", "03-Jun-2019");
callableStatement.setString("employee",null);
callableStatement.setInt("employeeOptional",1);
callableStatement.setString("sponsor", "abc");
callableStatement.setInt("sponsorOptional",0);
callableStatement.registerOutParameter("out_cursor", OracleTypes.CURSOR);
// run it
callableStatement.execute();
ResultSet rset = (ResultSet) callableStatement.getObject("out_cursor");
while(rset.next()) {
System.out.println(rset.getString("LABEL_VALUE"));
}
}catch(Exception e) {
e.printStackTrace();
}
以上代码运行良好,我也收到了ResultSet。但是问题是,如果我更改设置参数的顺序,它将不起作用。例如,如果我将sponsor
设置为高于日期,例如下面给出错误提示。
callableStatement.setString("protocols","12345");
callableStatement.setString("alertStartDate", "03-Apr-2019");
callableStatement.setString("sponsor", "abc");
callableStatement.setString("alertEndDate", "03-Jun-2019");
callableStatement.setString("employee",null);
callableStatement.setInt("employeeOptional",1);
callableStatement.setInt("sponsorOptional",0);
数据库错误是
ORA-01858:发现一个非数字字符,其中数字为 预期
ORA-06512:位于“ VIST_COMP”的第266行
使用构建路径Java 1.7(已安装JDK 1.8),Oracle 12c,Ojdbc6.jar。
答案 0 :(得分:0)
如果要使用命名参数来调用Oracle存储过程,可以考虑使用morejdbc。您的通话将如下所示:
import static org.morejdbc.NamedJdbcCall.call;
import org.morejdbc.*;
import org.springframework.jdbc.core.RowMapper;
// I do not know the structure of returned ref_cursor, so let it be a single column of varchar
RowMapper<String> mapper = (rs, rowNum) -> rs.getString("value");
Out<List<String>> resultOut = Out.of(OracleSqlTypes.cursor(mapper));
jdbcTemplate.execute(call("VIST_COMP")
.in("protocols", "12345") // note: argument name is Oracle PL/SQL argument name
.in("alert_start_date", "03-Apr-2019")
.in("alert_end_date", "03-Jun-2019")
.in("employee", null)
.in("employeeOptional", 1)
.in("sponsor", "abc")
.in("sponsorOptional", 0),
.out("out_cursor", resultOut));
System.out.println("Result is " + resultOut.get());
它需要Java 1.8和spring,但是如果您的项目有另一个堆栈,则可以方便地至少改写辅助类。