Java 通过JDBC调用Sybase存储过程时返回空结果集

Java 通过JDBC调用Sybase存储过程时返回空结果集,java,jdbc,sybase,Java,Jdbc,Sybase,我正在调用一个Sybase存储过程,它通过JDBC返回多个结果集。 我需要得到一个特定的结果集,它有一个名为“result”的列 这是我的代码: CallableStatement cs = conn.prepareCall(sqlCall); cs.registerOutParameter(1, Types.VARCHAR); cs.execute(); ResultSet rs=null; int count = 1; boolean flag = true; while (count &l

我正在调用一个Sybase存储过程,它通过JDBC返回多个结果集。 我需要得到一个特定的结果集,它有一个名为“result”的列 这是我的代码:

CallableStatement cs = conn.prepareCall(sqlCall);
cs.registerOutParameter(1, Types.VARCHAR);
cs.execute();
ResultSet rs=null;
int count = 1;
boolean flag = true;
while (count < 20000 && flag == true) {
    cs.getMoreResults();
    rs = cs.getResultSet();
    if (rs != null) {
        ResultSetMetaData resultSetMetaData = rs.getMetaData();
        int columnsCount = resultSetMetaData.getColumnCount();
        if (resultSetMetaData.getColumnName(1).equals("Result")) {
            // action code resultset found 
            flag = false;
            // loop on the resultset and add the elements returned to an array list
            while (rs.next()) {
                int x = 1;
                while (x <= columnsCount) {
                   result.add(rs.getString(x));
                   x++;
                }
            }
            result.add(0, cs.getString(1));
        }
    }
    count++;
}
CallableStatement cs=conn.prepareCall(sqlCall);
registerOutParameter(1,Types.VARCHAR);
cs.execute();
结果集rs=null;
整数计数=1;
布尔标志=真;
while(计数<20000&&flag==true){
cs.getMoreResults();
rs=cs.getResultSet();
如果(rs!=null){
ResultSetMetaData ResultSetMetaData=rs.getMetaData();
int columnsCount=resultSetMetaData.getColumnCount();
if(resultSetMetaData.getColumnName(1).equals(“结果”)){
//找到操作代码结果集
flag=false;
//循环并将返回的元素添加到数组列表中
while(rs.next()){
int x=1;

(x您误解了
getMoreResults()
的返回值。您还忽略了的返回值,此方法返回一个
布尔值,指示第一个结果的类型:

  • true
    :结果是一个
    ResultSet
  • false
    :结果是更新计数
如果结果为
true
,则使用来检索
ResultSet
,否则将检索更新计数。如果更新计数为
-1
,则表示没有更多的结果。请注意,当当前结果为
ResultSet
时,更新计数也将为
-1
。知道getResultSet()
应该返回null(最后一个条件就是为什么会得到这么多
null
值)

现在,如果要检索更多结果,可以调用(或其兄弟接受
int
参数)。
boolean
的返回值与
execute()
的返回值具有相同的含义,因此
false
并不意味着没有更多结果

只有当
getMoreResults()
返回false并且
getUpdateCount()
返回
-1
时,才会有更多的结果(正如Javadoc中所述)

本质上,这意味着如果您想正确处理所有结果,您需要执行以下操作:

boolean result = stmt.execute(...);
while(true) {
    if (result) {
        ResultSet rs = stmt.getResultSet();
        // Do something with resultset ...
    } else {
        int updateCount = stmt.getUpdateCount();
        if (updateCount == -1) {
            // no more results
            break;
        }
        // Do something with update count ...
    }
    result = stmt.getMoreResults();
}
我的猜测是,在获得实际的
ResultSet
之前,您会得到很多更新计数

我对Sybase不是很熟悉,但是它的同类SQL Server有一个“恼人”的特性,如果您没有在存储过程的开头显式地启用
SET NOCOUNT;
,它会从存储过程返回更新计数


注意:此答案的一部分基于我对

的回答,我在Sql Server中遇到了同样的问题,您的回答帮助我解决了这个问题。我不明白为什么
stmt.execute()
使用某些数据时会返回
false
,即使手动运行时可以清楚地看到返回的结果集中的数据。我仍然不确定是否理解
updateCount()
因为我不相信存储过程实际上正在更新任何数据。@Catfish您可以尝试在sp中添加
设置NOCOUNT ON
。我没有权限修改存储过程。您的答案似乎适用于我的情况。谢谢。