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 < 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++;
}

这里发生的是cs.getMoreResults返回大量的null结果集,直到它到达目标结果集.我不能将cs.getMoreResults用作循环条件,因为它为null结果集返回false.

我输入一个固定的数字来结束循环,条件是没有返回想要的结果集以防止它进入无限循环.它工作正常,但我不认为这是正确的.

我认为从Sybase中的赋值返回的null结果集选择@variable = value

以前有人遇到过这个吗?

解决方法:

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

> true:result是ResultSet
> false:结果是更新计数

如果结果为true,则使用getResultSet()检索ResultSet,否则使用getUpdateCount()检索更新计数.如果更新计数为-1,则表示没有更多结果.请注意,当前结果为ResultSet时,更新计数也将为-1.如果没有更多结果或者结果是更新计数,那么getResultSet()应该返回null也是一件好事(最后一个条件就是为什么你得到这么多空值).

现在,如果要检索更多结果,请调用getMoreResults()(或其兄弟接受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并不熟悉,但如果你没有明确地将SET NOCOUNT置为ON,它的堂兄SQL Server有“烦人”的功能来从存储过程返回更新计数.在存储过程的开始.

注意:这个答案的部分内容是基于我对Execute “sp_msforeachdb” in a Java application的回答

上一篇:C#委托和事件的使用示例


下一篇:C#.net连接Sybase的方法