对我来说,一个具有单独的游标记录字段的Java类,因为它是该类的成员和实例数组,它似乎是表示plsql CURSOR的正确方法。
我不同意。
如果您有一个存储的函数或过程返回了ref游标或将ref游标作为
OUT参数,则ref游标以形式出现在JDBC中
ResultSet。因此,如果可以使用
SYS_REFCURSOR参数调用存储过程,我怀疑a
ResultSet是您需要传递的内容。
实际上,我的怀疑得到了证实。如果你看一看Oracle的扩展
CallableStatement,
OracleCallableStatement,它继承了
setCursor(int,ResultSet)其超接口方法
OraclePreparedStatement。因此,您可以将转换
CallableStatement为
OracleCallableStatement,调用
setCursor方法,然后离开。
除了这种方法实际上不起作用。
如果尝试调用
setCursoran
OracleCallableStatement,则会出现异常
java.sql.SQLException:Unsupported feature。
你可以尝试调用
setObject了
ResultSet,但你只会得到另一个
java.sql.SQLException: Invalid columntype例外。
这是您可以运行以验证任一情况的测试类。它调用一个存储过程来获取ref游标(并因此获得
ResultSet),然后尝试将其传递给另一个:
import java.sql.*;import oracle.jdbc.OracleTypes;import oracle.jdbc.OracleCallableStatement;public class JavaRefCursorTest { public static void main(String[] args) throws Exception { Connection conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:XE", "user", "password"); try (CallableStatement cstmt1 = conn.prepareCall( "{ call java_ref_curs_test.get_ref_cursor(?)}")) { cstmt1.registerOutParameter(1, OracleTypes.CURSOR); cstmt1.execute(); try (ResultSet rSet = (ResultSet)cstmt1.getObject(1)) { try (CallableStatement cstmt2 = conn.prepareCall( "{ call java_ref_curs_test.print_refcursor(?)}")) { // Uncomment the next line to call setCursor: // ((OracleCallableStatement)cstmt2).setCursor(1, rSet); // Uncomment the next line to call setObject: // cstmt2.setObject(1, rSet); cstmt2.execute(); } } } }}(采用
java_ref_curs_test单个
SYS_REFCURSOR参数的两个过程:
get_ref_cursor返回一个ref游标,
print_refcursor并将一个作为参数,但不执行任何操作。)
那么,
setXXX您应该使用哪种方法?我什么也不会说。您要的内容无法直接实现。
仍然可以调用此过程,但是您必须在PL / SQL(而不是Java)中创建ref游标,然后将其传递给过程。
例如,我可以使用以下PL / SQL块来调用以上示例中使用的两个过程:
DECLARE l_curs SYS_REFCURSOR;BEGIN java_ref_curs_test.get_ref_cursor(l_curs); java_ref_curs_test.print_refcursor(l_curs); END;
您可以从JDBC轻松运行此代码:将其放入字符串中并将其传递给
Statement.executeUpdate()。



