我使用JDBC
从正在使用SYS_REFCURSOR
的Oracle存储过程中获取结果。当我在sqlPlus
中执行存储过程时,我得到结果,但在Java中,我得到一个空的结果集。
我在下面找到了问题here,这似乎是完美的解决方案,除了它不起作用。
从我的日志中 - 这是构造的最终字符串:
致电ENT_GET_USERS
(?,?,?,?)
有人可以建议我为什么通过Java获取空结果集吗?
我正在使用stmt.registerOutParameter(columnName, OracleTypes.CURSOR);
正如上面的链接所示,我更改了我的代码,为String参数
设置""
case Types.VARCHAR:
if (inputValue != null)
stmt.setString(columnName, inputValue);
else
stmt.setString(columnName, "");
我的程序定义如下:
CREATE OR REPLACE PROCEDURE ENT_GET_USERS( p_id VARCHAR2 , p_id_type VARCHAR2, p_app_id VARCHAR2 , usr_result OUT SYS_REFCURSOR )
EDIT1 : 我从sqlplus打电话,如下所示
SQL> variable rc refcursor;
SQL> exec ENT_GET_USERS(NULL , 'APP' , NULL , :rc ) ;
PL / SQL程序已成功完成。
SQL>打印rc; //返回结果
EDIT2 : 我创建了一个测试程序,并使用缩短版的Procedure而没有运气。代码如下:
CallableStatement cstmt = conn
.prepareCall("{call ETTRDV_EMEA.ENT_GET_USERS (?,?,?,?)}");
cstmt.registerOutParameter("usr_result", OracleTypes.CURSOR); // REF CURSOR
cstmt.setString("p_id", "-1");
cstmt.setString("p_id_type", "APP");
cstmt.setString("p_app_id", "");
cstmt.execute(); //updated
ResultSet rs = (ResultSet)cstmt.getObject("usr_result");
while (rs.next()){
System.out.println("Next");
}
输出:接下来..等等 - 它有效!
以下程序:
CREATE OR REPLACE PROCEDURE ENT_GET_USERS( p_id VARCHAR2 ,
p_id_type VARCHAR2,
p_app_id VARCHAR2 ,
usr_result OUT SYS_REFCURSOR) AS
BEGIN
OPEN usr_result for SELECT USR.USR_ID , USR.USR_SID, USR.USR_FIRSTNAME , USR.USR_LASTNAME , USR.REFERENCE_ID , USR.USR_CREATED_BY , USR.USR_CREATED_ON , USR.USR_UPDATED_BY , USR.USR_UPDATED_ON
FROM ENT_USERS USR ;
END;
从SQLPLUS执行:
exec ENT_GET_USERS('-1' , 'APP' , '', :rc ) ;
这给了我预期的结果。
我做错了什么?
EDIT3: 更新了上面的工作代码。
答案 0 :(得分:0)
booleanresult 应为假;这并不意味着引用游标是空的。 From the documentation:
execute方法返回一个布尔值以指示第一个结果的形式。您必须调用方法getResultSet或getUpdateCount来检索结果;你必须调用getMoreResults来移动到任何后续的结果。
<强>返回:强>
,则返回false
如果第一个结果是ResultSet对象,则为true;否则为false。如果第一个结果是更新计数或没有结果
程序调用没有结果。返回值与此调用恰好具有的out参数以及恰好是游标的out参数是否包含任何内容无关。
由于您已经在SQL * Plus中尝试过此操作,此时它基本上就像您已经完成了exec
,但您还没有对{做出任何事情{ {1}}。
您需要获取光标,例如:
:rc
或者您没有使用OracleCallableStatement:
ResultSet rset = cstmt.getCursor("usr_result");
然后迭代结果集,就像使用查询创建的一样。
我已经将命名参数的结果混合在一起,特别是在以与定义它们的顺序不同的顺序设置它们时。您可能会发现需要使用ResultSet rset = (ResultSet) cstmt.getObject("usr_result");
或getCursor(4)
。