如何使用Java中的ResultSet获取行数?

我想创build一个简单的方法接收一个ResultSet作为参数,并返回一个包含ResultSet的行数的int。 这是做这个还是不这么做的有效方法?

int size = 0; try { while(rs.next()){ size++; } } catch(Exception ex) { System.out.println("------------------Tablerize.getRowCount-----------------"); System.out.println("Cannot get resultSet row count: " + ex); System.out.println("--------------------------------------------------------"); } 

我试过这个:

 int size = 0; try { resultSet.last(); size = resultSet.getRow(); resultSet.beforeFirst(); } catch(Exception ex) { return 0; } return size; 

但是我得到一个错误,说com.microsoft.sqlserver.jdbc.SQLServerException: The requested operation is not supported on forward only result sets.

在此先感谢指针!

如果您有权访问导致此结果集的准备好的语句,则可以使用

 connection.prepareStatement(sql, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); 

这可以使您的语句准备就绪,您可以倒带光标。 这也logging在ResultSet Javadoc中

但是,一般来说,对于大的结果集,转发和倒带游标可能是相当低效的。 SQL Server中的另一个select是直接计算SQL语句中的总行数:

 SELECT my_table.*, count(*) over (partition by 1) total_rows FROM my_table WHERE ... 

你的sql语句创build代码可能就像

 statement = connection.createStatement(); 

要解决“com.microsoft.sqlserver.jdbc.SQLServerException:请求的操作不支持仅前向结果集”exception更改上面的代码

 statement = connection.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); 

上述更改后,您可以使用

 int size = 0; try { resultSet.last(); size = resultSet.getRow(); resultSet.beforeFirst(); } catch(Exception ex) { return 0; } return size; 

得到行数

 Statement s = cd.createStatement(); ResultSet r = s.executeQuery("SELECT COUNT(*) AS rowcount FROM FieldMaster"); r.next(); int count = r.getInt("rowcount"); r.close(); System.out.println("MyTable has " + count + " row(s)."); 

有时候JDBC不支持以下方法给出类似`TYPE_FORWARD_ONLY'的错误使用这个解决scheme

Sqlite不支持JDBC。

 resultSet.last(); size = resultSet.getRow(); resultSet.beforeFirst(); 

所以那个时候使用这个解决scheme。

谢谢..

做一个SELECT COUNT(*) FROM ...查询。

我只是做了一个getter方法。

 public int getNumberRows(){ try{ statement = connection.creatStatement(); resultset = statement.executeQuery("your query here"); if(resultset.last()){ return resultset.getRow(); } else { return 0; //just cus I like to always do some kinda else statement. } } catch (Exception e){ System.out.println("Error getting row count"); e.printStackTrace(); } return 0; } 

如果你有表和存储ID为主要和自动增量,那么这将工作

获取总行数的示例代码http://www.java2s.com/Tutorial/Java/0340__Database/GettheNumberofRowsinaDatabaseTable.htm

以下是代码

 import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.Statement; public class Main { public static void main(String[] args) throws Exception { Connection conn = getConnection(); Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); st.executeUpdate("create table survey (id int,name varchar(30));"); st.executeUpdate("insert into survey (id,name ) values (1,'nameValue')"); st.executeUpdate("insert into survey (id,name ) values (2,null)"); st.executeUpdate("insert into survey (id,name ) values (3,'Tom')"); st = conn.createStatement(); ResultSet rs = st.executeQuery("SELECT * FROM survey"); rs = st.executeQuery("SELECT COUNT(*) FROM survey"); // get the number of rows from the result set rs.next(); int rowCount = rs.getInt(1); System.out.println(rowCount); rs.close(); st.close(); conn.close(); } private static Connection getConnection() throws Exception { Class.forName("org.hsqldb.jdbcDriver"); String url = "jdbc:hsqldb:mem:data/tutorial"; return DriverManager.getConnection(url, "sa", ""); } } 

你的函数将返回一个ResultSet的大小,但是它的游标将被设置在最后一个logging之后,所以如果没有通过调用beforeFirst(),first()或previous()来倒回,你将无法读取它的行,方法将不能用于只向前ResultSet(你会得到同样的例外,你在第二个代码片段)。

大多数驱动程序仅支持向前结果集 – 因此不支持像last,beforeFirst等方法。

第一种方法适用于在同一个循环中获取数据的情况 – 否则resultSet已经迭代过,不能再使用。

在大多数情况下,要求是获取查询将返回的行数而不提取行。 遍历结果集以查找行数几乎与处理数据相同。 代替另一个计数(*)查询更好。

其他人已经回答了如何解决你的问题,所以我不会重复已经说过的话,但是我会这么说:你应该想办法解决你的问题,而不必知道结果集计数,结果。

在阅读结果集之前实际需要行计数的情况很less,特别是在像Java这样的语言中。 唯一的情况下,我想在哪里行数是必要的行计数是唯一你需要的数据(在这种情况下计数查询将是优越的)。 否则,最好使用包装器对象来表示表数据,并将这些对象存储在dynamic容器(如ArrayList)中。 然后,一旦结果集被迭代,你可以得到数组列表的数量。 对于需要在读取结果集之前就知道行数的每个解决scheme,您可能会想到一个解决scheme,在阅读之前不需要知道行数就可以省力。 通过考虑在处理之前绕过需要知道行数的解决scheme,可以将ResultSet的滚动问题保存到结果集的末尾,然后返回到开始(对于大型结果集,这可能是一个非常昂贵的操作) 。

当然,我并不是说在阅读结果集之前,不会有任何需要行计数的情况。 我只是说,在大多数情况下,当人们认为他们在阅读之前需要结果集计数时,他们可能不需要,花5分钟去思考是否有另一种方法。

只是想提供我的2分钱的话题。

ResultSet具有根据提供的选项来回移动光标的方法。 默认情况下,它正在向前移动(TYPE_FORWARD_ONLY结果集types)。 除非CONSTANTS正确指示可滚动性和结果集的更新,否则最终可能会出现错误。 例如beforeLast()如果结果集不包含行,则此方法无效。 抛出错误,如果它不是TYPE_FORWARD_ONLY。

检查空行是否被获取的最好方法是在检查不存在之后插入新logging

 if( rs.next() ){ Do nothing } else { No records fetched! } 

看到这里

这里有一些代码可以避免计数实例化一个数组,而是使用一个ArrayList,而不是在返回之前将ArrayList转换为所需的数组types。

请注意,这里的Supervisor类实现ISupervisor接口,但在Java中,您不能从object [](ArrayList的toArray()方法返回的)转换到ISupervisor [](因为我认为您可以在C#中完成)必须遍历所有列表项并填充结果数组。

 /** * Get Supervisors for given program id * @param connection * @param programId * @return ISupervisor[] * @throws SQLException */ public static ISupervisor[] getSupervisors(Connection connection, String programId) throws SQLException { ArrayList supervisors = new ArrayList(); PreparedStatement statement = connection.prepareStatement(SQL.GET_SUPERVISORS); try { statement.setString(SQL.GET_SUPERVISORS_PARAM_PROGRAMID, programId); ResultSet resultSet = statement.executeQuery(); if (resultSet != null) { while (resultSet.next()) { Supervisor s = new Supervisor(); s.setId(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ID)); s.setFirstName(resultSet.getString(SQL.GET_SUPERVISORS_RESULT_FIRSTNAME)); s.setLastName(resultSet.getString(SQL.GET_SUPERVISORS_RESULT_LASTNAME)); s.setAssignmentCount(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ASSIGNMENT_COUNT)); s.setAssignment2Count(resultSet.getInt(SQL.GET_SUPERVISORS_RESULT_ASSIGNMENT2_COUNT)); supervisors.add(s); } resultSet.close(); } } finally { statement.close(); } int count = supervisors.size(); ISupervisor[] result = new ISupervisor[count]; for (int i=0; i<count; i++) result[i] = (ISupervisor)supervisors.get(i); return result; } 

以下两个选项为我工作:

1)返回ResultSet中行数的函数。

 private int resultSetCount(ResultSet resultSet) throws SQLException{ try{ int i = 0; while (resultSet.next()) { i++; } return i; } catch (Exception e){ System.out.println("Error getting row count"); e.printStackTrace(); } return 0; } 

2)用COUNT选项创build第二个SQL语句。

http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/ResultSetMetaData.html

  ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2"); ResultSetMetaData rsmd = rs.getMetaData(); int numberOfColumns = rsmd.getColumnCount(); 

ResultSet包含给出行数的元数据。