JDBC调用返回Cursor的Oracle函数报错求助
解决Oracle函数返回游标Java调用失败的问题
先修正代码中的基础错误
你的Java代码存在几个明显的语法/API使用错误,这是导致报错的直接原因之一:
- 不存在
setUserCompany方法:设置字符串类型参数应该用callStmt.setString() - 拼写错误:
System.currentTimeMilis()→ 正确写法是System.currentTimeMillis() - 字符串定义错误:第二种写法里的
String sqlQuery = """;语法非法,应该写成String sqlQuery = "begin ? := getUserSelection(?,?,?,?); end;"; - 参数设置方法错误:
callStmt.set("p_mode", 0)应该用对应类型的方法,比如setInt()
正确的Java调用示例(推荐使用匿名块+位置参数)
Oracle JDBC对匿名块的支持更稳定,以下是修正后的完整代码:
String sqlQuery = "begin ? := getUserSelection(?,?,?,?); end;"; CallableStatement callStmt = con.prepareCall(sqlQuery); // 注册输出游标参数(位置1) callStmt.registerOutParameter(1, OracleTypes.CURSOR); // 设置输入参数(位置2到5) callStmt.setInt(2, 123); callStmt.setDate(3, new java.sql.Date(System.currentTimeMillis())); callStmt.setString(4, "Kiwi"); callStmt.setInt(5, 0); // 如果不需要p_mode,可以省略这个参数,写成getUserSelection(?,?,?) callStmt.execute(); // 获取游标结果 ResultSet rs = (ResultSet) callStmt.getObject(1); // 处理结果集 while (rs.next()) { // 根据实际字段获取数据,比如rs.getString("COLUMN_NAME") } // 关闭资源 rs.close(); callStmt.close();
额外注意事项
- 如果要使用命名参数,需要确保Oracle JDBC驱动版本支持,并且参数名要和函数定义的完全一致(包括大小写,Oracle默认不区分,但最好保持一致),同时注册输出参数时要使用参数名对应的位置或者正确的命名方式:
callStmt.registerOutParameter("v_c", OracleTypes.CURSOR); // 注意:命名参数的使用需要驱动支持,部分版本可能需要开启特定配置 - 确认函数的
p_userCompany参数类型:Oracle里没有string类型,实际应该是varchar2,Java用setString对应是正确的 - 如果
p_mode是可选参数(有默认值),调用时可以省略该参数,SQL语句改成begin ? := getUserSelection(?,?,?); end;,同时去掉对应的setInt步骤
内容的提问来源于stack exchange,提问作者DigitalMachine
相关产品推荐
相关产品推荐

