我正在尝试创建一个简单的方法,它接收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.
提前感谢指针!
答案 0 :(得分:56)
如果您有权访问导致此结果集的预准备语句,则可以使用
connection.prepareStatement(sql,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
这会以您可以回放光标的方式准备语句。这也记录在ResultSet Javadoc
中但是,一般情况下,对于大型结果集,转发和倒带游标可能效率很低。 SQL Server中的另一个选项是直接在SQL语句中计算总行数:
SELECT my_table.*, count(*) over () total_rows
FROM my_table
WHERE ...
答案 1 :(得分:33)
你的sql语句创建代码可能就像
statement = connection.createStatement();
解决“com.microsoft.sqlserver.jdbc.SQLServerException:仅向前转发结果集不支持请求的操作”异常更改代码
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;
获取行数
答案 2 :(得分:20)
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'使用此解决方案
Sqlite在JDBC中不支持。
resultSet.last();
size = resultSet.getRow();
resultSet.beforeFirst();
那时候使用这个解决方案。
谢谢..
答案 3 :(得分:7)
改为执行SELECT COUNT(*) FROM ...
查询。
答案 4 :(得分:5)
我刚做了一个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;
}
答案 5 :(得分:3)
如果你有表并将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", "");
}
}
答案 6 :(得分:2)
你的函数将返回ResultSet的大小,但是它的光标将在最后一条记录之后设置,所以不通过调用beforeFirst(),first()或previous()来重绕它,你将无法读取它的行,并且倒带方法不适用于仅向前ResultSet(您将获得与第二个代码片段相同的异常)。
答案 7 :(得分:2)
大多数驱动程序仅支持转发结果集 - 因此不支持像last,beforeFirst等方法。
如果您也在同一个循环中获取数据,则第一种方法是合适的 - 否则resultSet已经被迭代并且不能再次使用。
在大多数情况下,要求是获取查询在不获取行的情况下返回的行数。迭代结果集以查找行计数与处理数据几乎相同。最好再做一次count(*)查询。
答案 8 :(得分:2)
其他人已经回答了如何解决你的问题,所以我不会重复已经说过的话,但我会说:你应该想办法解决你的问题而不知道结果集的数量在阅读结果之前。
在读取结果集之前,实际需要行计数的情况非常少,特别是在像Java这样的语言中。我认为唯一需要行计数的情况是行数是您需要的唯一数据(在这种情况下,计数查询会更好)。否则,最好使用包装器对象来表示表数据,并将这些对象存储在动态容器(如ArrayList)中。然后,一旦迭代结果集,就可以获得数组列表计数。对于需要在读取结果集之前知道行数的每个解决方案,您可能会想到一个解决方案,在不花费精力阅读之前不知道行数。通过考虑绕过在处理之前知道行计数的需要的解决方案,可以保存ResultSet滚动到结果集末尾的麻烦,然后回到开头(这对于大型结果集来说可能是非常昂贵的操作) 。
现在我当然不是说在读取结果集之前从未出现过需要行计数的情况。我只是说,在大多数情况下,当人们认为在阅读之前他们需要结果集计数时,他们可能不会,并且值得花5分钟考虑是否有另一种方式。
只是想在这个主题上提供2美分。
答案 9 :(得分:1)
ResultSet有它的方法可以根据提供的选项来回移动Cursor。默认情况下,它向前移动(TYPE_FORWARD_ONLY结果集类型)。 除非CONSTANTS正确指示可滚动性和结果集更新,否则您最终可能会收到错误。 例如。 beforeLast() 如果结果集不包含任何行,则此方法无效。 如果它不是TYPE_FORWARD_ONLY则会引发错误。
检查是否已获取空行的最佳方法---只是在检查不存在后插入新记录
if( rs.next() ){
Do nothing
} else {
No records fetched!
}
请参阅here
答案 10 :(得分:0)
这里有一些代码可以避免计数实例化数组,但是使用ArrayList而不是在返回之前将ArrayList转换为所需的数组类型。
请注意,Supervisor类在这里实现了ISupervisor接口,但在Java中你无法从object [](ArrayList的plain 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;
}
答案 11 :(得分:0)
以下两个选项适用于我:
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选项创建第二个SQL语句。
答案 12 :(得分:-7)
来自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包含提供行数的元数据。