通过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结果集select @variable = value
以前有人遇到过这个吗?
您误解了getMoreResults()
的返回值。 您也忽略了execute()
的返回值,此方法返回一个boolean
指示第一个结果的类型:
-
true
:result是ResultSet
-
false
:结果是更新计数
如果结果为true
,则使用getResultSet()
来检索ResultSet
,否则使用getUpdateCount()
来检索更新计数。 如果更新计数为-1
则表示没有更多结果。 请注意,当前结果为ResultSet
时,更新计数也将为-1
。 如果没有更多结果或者结果是更新计数,那么getResultSet()
应该返回null也是一件好事(最后一个条件就是为什么你得到这么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有“烦人”function来从存储过程返回更新计数SET NOCOUNT ON;
在存储过程的开始。
注意:此答案的一部分基于我在Java应用程序中对Execute“sp_msforeachdb”的回答