新手问题......任何人都可以提供对PL / SQL存储过程(驻留在数据库Linux服务器中)需要完成的事情的高级描述,以便将数据发送到Java程序(在应用程序服务器中) ?
更新1
以下elrado的回答让我前进(谢谢!)。我可以看到PL / SQL存储过程只需要将OUT参数设置为REF CURSOR(例如SYS_REFCURSOR)。然后,调用Java例程可以使用以下内容:import oracle.jdbc.*;
...
// call stored procedure using SQL92 syntax
CallableStatement cs = conn.prepareCall( "{call myStoredProc (?,?,?,?,?)}" );
// set IN parameters
cs.setString(1, in1var);
cs.setString(2, in2var);
cs.setString(3, in3var);
// register OUT parameters
cs.registerOutParameter(4, Types.VARCHAR);
cs.registerOutParameter(5, OracleTypes.CURSOR);
// execute and retrieve Oracle "ref cursor" as a Java "ResultSet"
cs.execute();
rs = (ResultSet) cs.getObject(5);
// process result
while (rs.next()) {
...
}
// always retrieve ResultSet before OUT parameters
out1var = cs.getInt(4);
问题1:上述情况看起来不错吗?
我在Oracle的文档中看到(请参阅第4-14到4-15页http://isu.ifmo.ru/docs/doc112/java.112/e10589.pdf),我应该使用OracleCallableStatement
而不是CallableStatement
,这样它应该如下所示:
// execute and retrieve Oracle "ref cursor" as a Java "ResultSet"
cs.execute();
rs = {(OracleCallableStatement)cs}.getCursor(5);
问题2:这两种方法都没问题吗?如果是这样,那么使用一个而不是另一个的专业人士和骗子是什么?
问题3:我不理解第4-15页关于Oracle 11G数据库的Important
注释:
Unlike in past releases, the cursor associated with a REF CURSOR is not closed when the result set object in which the REF CURSOR was materialized is closed.
这是否意味着ref cursor
在cs
关闭时关闭(与以前的数据库版本相反,而当ref cursor
关闭时关闭rs
?)
答案 0 :(得分:4)
如果要从Oralce PL / SQL过程返回结果集,请使用ref cursor:
http://www.oracle-base.com/articles/misc/UsingRefCursorsToReturnRecordsets.php
Q1:是的,看起来不错,但我没有测试过。 的 Q2:强> 我相信OracleCallableStatement只是扩展了CallableStatement。两者都很好,但是在可能的情况下我使用Oracle驱动程序连接并使用Oracle db(而不是一些通用驱动程序)。
问题3:我相信你是对的,当你关闭结果集时,光标会保持打开状态。(自从我从程序中读取结果集以来已经有一段时间了,所以我不记得何时关闭光标对不起现在我在家,无法访问Oracle数据库和我的工作计算机。)
答案 1 :(得分:0)
如果您的数据库框架是spring-jdbc
,则可以尝试使用morejdbc(在Maven Central中可用)。通话看起来像
import static org.morejdbc.NamedJdbcCall.call;
import static org.morejdbc.SqlTypes.*;
import org.morejdbc.*;
...
// note: it can be either INTEGER or VARCHAR - you declare one type, but get result via another
Out<Integer> out4 = Out.of(INTEGER);
// you did not declare the structure of cursor result set, so assume it's a single column of VARCHAR
Out<List<String>> out5 = OracleSqlTypes.cursor((rs, rowNum) -> rs.getString(1));
// named parameter binding is used, hence argument declaration order can be any
jdbcTemplate.execute(call("myStoredProc")
.in("in1", in1var)) // note: first argument is pl/sql parameter name
.in("in2", in2var)
.in("in3", in3var)
.out("out4", out4)
.out("out5", out5)); // will close REF_CURSOR automatically
System.out.println("out4 is " + out4.get());
System.out.println("out5 is " + out5.get());
Q2:我已经使用驱动程序wnameless/oracle-xe-11g-r2
检查了docker image 11.2.0.4
,两个OUT参数检索顺序都很好。