如何获取 java.sql.ResultSet 的大小?

发布于 2024-07-06 16:22:16 字数 82 浏览 7 评论 0原文

这不是一个非常简单的操作吗? 但是,我发现既没有 size() 也没有 length() 方法。

Shouldn't this be a pretty straightforward operation? However, I see there's neither a size() nor length() method.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

赤濁 2024-07-13 16:22:16

请执行 SELECT COUNT(*) FROM ... 查询。

或者

int size =0;
if (rs != null) 
{
  rs.last();    // moves cursor to the last row
  size = rs.getRow(); // get row id 
}

在任何一种情况下,您都不必循环整个数据。

Do a SELECT COUNT(*) FROM ... query instead.

OR

int size =0;
if (rs != null) 
{
  rs.last();    // moves cursor to the last row
  size = rs.getRow(); // get row id 
}

In either of the case, you won't have to loop over the entire data.

无远思近则忧 2024-07-13 16:22:16
ResultSet rs = ps.executeQuery();
int rowcount = 0;
if (rs.last()) {
  rowcount = rs.getRow();
  rs.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element
}
while (rs.next()) {
  // do your standard per row stuff
}
ResultSet rs = ps.executeQuery();
int rowcount = 0;
if (rs.last()) {
  rowcount = rs.getRow();
  rs.beforeFirst(); // not rs.first() because the rs.next() below will move on, missing the first element
}
while (rs.next()) {
  // do your standard per row stuff
}
夜空下最亮的亮点 2024-07-13 16:22:16

好吧,如果您有一个 ResultSet.TYPE_FORWARD_ONLY 类型的 ResultSet,您希望保持这种方式(并且切换到 ResultSet.TYPE_SCROLL_INSENSITIVEResultSet.TYPE_SCROLL_INSENSITIVE 以便能够使用 .last())。

我建议一个非常好的和有效的技巧,您可以在顶部添加第一个包含行数的假/假行。

示例

假设您的查询如下,

select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR
from MYTABLE
where ...blahblah...

您的输出如下所示

true    65537 "Hey" -32768 "The quick brown fox"
false  123456 "Sup"    300 "The lazy dog"
false -123123 "Yo"       0 "Go ahead and jump"
false       3 "EVH"    456 "Might as well jump"
...
[1000 total rows]

只需将代码重构为如下所示:

Statement s=myConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
                                         ResultSet.CONCUR_READ_ONLY);
String from_where="FROM myTable WHERE ...blahblah... ";
//h4x
ResultSet rs=s.executeQuery("select count(*)as RECORDCOUNT,"
                           +       "cast(null as boolean)as MYBOOL,"
                           +       "cast(null as int)as MYINT,"
                           +       "cast(null as char(1))as MYCHAR,"
                           +       "cast(null as smallint)as MYSMALLINT,"
                           +       "cast(null as varchar(1))as MYVARCHAR "
                           +from_where
                           +"UNION ALL "//the "ALL" part prevents internal re-sorting to prevent duplicates (and we do not want that)
                           +"select cast(null as int)as RECORDCOUNT,"
                           +       "MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR "
                           +from_where);

您的查询输出现在将类似于

1000 null     null null    null null
null true    65537 "Hey" -32768 "The quick brown fox"
null false  123456 "Sup"    300 "The lazy dog"
null false -123123 "Yo"       0 "Go ahead and jump"
null false       3 "EVH"    456 "Might as well jump"
...
[1001 total rows]

所以您只需

if(rs.next())
    System.out.println("Recordcount: "+rs.getInt("RECORDCOUNT"));//hack: first record contains the record count
while(rs.next())
    //do your stuff

Well, if you have a ResultSet of type ResultSet.TYPE_FORWARD_ONLY you want to keep it that way (and not to switch to a ResultSet.TYPE_SCROLL_INSENSITIVE or ResultSet.TYPE_SCROLL_INSENSITIVE in order to be able to use .last()).

I suggest a very nice and efficient hack, where you add a first bogus/phony row at the top containing the number of rows.

Example

Let's say your query is the following

select MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR
from MYTABLE
where ...blahblah...

and your output looks like

true    65537 "Hey" -32768 "The quick brown fox"
false  123456 "Sup"    300 "The lazy dog"
false -123123 "Yo"       0 "Go ahead and jump"
false       3 "EVH"    456 "Might as well jump"
...
[1000 total rows]

Simply refactor your code to something like this:

Statement s=myConnection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
                                         ResultSet.CONCUR_READ_ONLY);
String from_where="FROM myTable WHERE ...blahblah... ";
//h4x
ResultSet rs=s.executeQuery("select count(*)as RECORDCOUNT,"
                           +       "cast(null as boolean)as MYBOOL,"
                           +       "cast(null as int)as MYINT,"
                           +       "cast(null as char(1))as MYCHAR,"
                           +       "cast(null as smallint)as MYSMALLINT,"
                           +       "cast(null as varchar(1))as MYVARCHAR "
                           +from_where
                           +"UNION ALL "//the "ALL" part prevents internal re-sorting to prevent duplicates (and we do not want that)
                           +"select cast(null as int)as RECORDCOUNT,"
                           +       "MYBOOL,MYINT,MYCHAR,MYSMALLINT,MYVARCHAR "
                           +from_where);

Your query output will now be something like

1000 null     null null    null null
null true    65537 "Hey" -32768 "The quick brown fox"
null false  123456 "Sup"    300 "The lazy dog"
null false -123123 "Yo"       0 "Go ahead and jump"
null false       3 "EVH"    456 "Might as well jump"
...
[1001 total rows]

So you just have to

if(rs.next())
    System.out.println("Recordcount: "+rs.getInt("RECORDCOUNT"));//hack: first record contains the record count
while(rs.next())
    //do your stuff
谈下烟灰 2024-07-13 16:22:16
int i = 0;
while(rs.next()) {
    i++;
}
int i = 0;
while(rs.next()) {
    i++;
}
隔纱相望 2024-07-13 16:22:16

我在使用 rs.last() 时遇到异常

if(rs.last()){
    rowCount = rs.getRow(); 
    rs.beforeFirst();
}

java.sql.SQLException: Invalid operation for forward only resultset

这是因为默认情况下它是 ResultSet.TYPE_FORWARD_ONLY ,这意味着您只能使用 rs.next( )

解决方案是:

stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_READ_ONLY); 

I got an exception when using rs.last()

if(rs.last()){
    rowCount = rs.getRow(); 
    rs.beforeFirst();
}

:

java.sql.SQLException: Invalid operation for forward only resultset

it's due to by default it is ResultSet.TYPE_FORWARD_ONLY, which means you can only use rs.next()

the solution is:

stmt=conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet.CONCUR_READ_ONLY); 
前事休说 2024-07-13 16:22:16

[速度考虑]

这里很多人建议 ResultSet.last() 但为此,您需要以 ResultSet.TYPE_SCROLL_INSENSITIVE 的形式打开连接,对于 Derby 嵌入式数据库来说,最多可达比 ResultSet.TYPE_FORWARD_ONLY 10 倍。

根据我对嵌入式 Derby 和 H2 数据库的微观测试,在 SELECT 之前调用 SELECT COUNT(*) 速度要快得多。

这是我的代码和基准的更详细信息

[Speed consideration]

Lot of ppl here suggests ResultSet.last() but for that you would need to open connection as a ResultSet.TYPE_SCROLL_INSENSITIVE which for Derby embedded database is up to 10 times SLOWER than ResultSet.TYPE_FORWARD_ONLY.

According to my micro-tests for embedded Derby and H2 databases it is significantly faster to call SELECT COUNT(*) before your SELECT.

Here is in more detail my code and my benchmarks

別甾虛僞 2024-07-13 16:22:16

获取 ResultSet 大小的方法,不需要使用 ArrayList 等

int size =0;  
if (rs != null)   
{  
rs.beforeFirst();  
 rs.last();  
size = rs.getRow();
}

现在你将获得大小,如果你想打印 ResultSet,在打印之前也使用以下代码行,

rs.beforeFirst();  

The way of getting size of ResultSet, No need of using ArrayList etc

int size =0;  
if (rs != null)   
{  
rs.beforeFirst();  
 rs.last();  
size = rs.getRow();
}

Now You will get size, And if you want print the ResultSet, before printing use following line of code too,

rs.beforeFirst();  
鱼窥荷 2024-07-13 16:22:16

这是进行行计数的简单方法。

ResultSet rs = job.getSearchedResult(stmt);
int rsCount = 0;

//but notice that you'll only get correct ResultSet size after end of the while loop
while(rs.next())
{
    //do your other per row stuff 
    rsCount = rsCount + 1;
}//end while

It is a simple way to do rows-count.

ResultSet rs = job.getSearchedResult(stmt);
int rsCount = 0;

//but notice that you'll only get correct ResultSet size after end of the while loop
while(rs.next())
{
    //do your other per row stuff 
    rsCount = rsCount + 1;
}//end while
兰花执着 2024-07-13 16:22:16
String sql = "select count(*) from message";
ps =  cn.prepareStatement(sql);

rs = ps.executeQuery();
int rowCount = 0;
while(rs.next()) {
    rowCount = Integer.parseInt(rs.getString("count(*)"));
    System.out.println(Integer.parseInt(rs.getString("count(*)")));
}
System.out.println("Count : " + rowCount);
String sql = "select count(*) from message";
ps =  cn.prepareStatement(sql);

rs = ps.executeQuery();
int rowCount = 0;
while(rs.next()) {
    rowCount = Integer.parseInt(rs.getString("count(*)"));
    System.out.println(Integer.parseInt(rs.getString("count(*)")));
}
System.out.println("Count : " + rowCount);
离线来电— 2024-07-13 16:22:16
theStatement=theConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

ResultSet theResult=theStatement.executeQuery(query); 

//Get the size of the data returned
theResult.last();     
int size = theResult.getRow() * theResult.getMetaData().getColumnCount();       
theResult.beforeFirst();
theStatement=theConnection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

ResultSet theResult=theStatement.executeQuery(query); 

//Get the size of the data returned
theResult.last();     
int size = theResult.getRow() * theResult.getMetaData().getColumnCount();       
theResult.beforeFirst();
彩虹直至黑白 2024-07-13 16:22:16

我检查了ResultSet接口的运行时值,发现它几乎一直是一个ResultSetImpl。 ResultSetImpl 有一个名为 getUpdateCount() 的方法,它返回您正在查找的值。

这个代码示例应该足够了:
ResultSet resultSet =executeQuery(sqlQuery);
double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()

我意识到向下转型通常是一个不安全的过程,但这个方法还没有让我失望。

I checked the runtime value of the ResultSet interface and found out it was pretty much a ResultSetImpl all the time. ResultSetImpl has a method called getUpdateCount() which returns the value you are looking for.

This code sample should suffice:
ResultSet resultSet = executeQuery(sqlQuery);
double rowCount = ((ResultSetImpl)resultSet).getUpdateCount()

I realize that downcasting is generally an unsafe procedure but this method hasn't yet failed me.

佞臣 2024-07-13 16:22:16

今天我用这个逻辑为什么我不知道得到RS的计数。

int chkSize = 0;
if (rs.next()) {
    do {  ..... blah blah
        enter code here for each rs.
        chkSize++;
    } while (rs.next());
} else {
    enter code here for rs size = 0 
}
// good luck to u.

Today, I used this logic why I don't know getting the count of RS.

int chkSize = 0;
if (rs.next()) {
    do {  ..... blah blah
        enter code here for each rs.
        chkSize++;
    } while (rs.next());
} else {
    enter code here for rs size = 0 
}
// good luck to u.
剧终人散尽 2024-07-13 16:22:16

我也遇到了同样的问题。 在执行后以这种方式使用 ResultSet.first() 解决了这个问题:

if(rs.first()){
    // Do your job
} else {
    // No rows take some actions
}

文档(链接):

布尔值优先() 
      抛出 SQLException 
  

将光标移动到此 ResultSet 对象中的第一行。

退货:

true 如果光标位于有效的位置
排; false 如果结果集中没有行

抛出:

SQLException - 如果发生数据库访问错误; 在封闭结果集上调用此方法或结果集类型为TYPE_FORWARD_ONLY

SQLFeatureNotSupportedException - 如果 JDBC 驱动程序不支持
这个方法

自:

1.2

I was having the same problem. Using ResultSet.first() in this way just after the execution solved it:

if(rs.first()){
    // Do your job
} else {
    // No rows take some actions
}

Documentation (link):

boolean first()
    throws SQLException

Moves the cursor to the first row in this ResultSet object.

Returns:

true if the cursor is on a valid
row; false if there are no rows in the result set

Throws:

SQLException - if a database access error occurs; this method is called on a closed result set or the result set type is TYPE_FORWARD_ONLY

SQLFeatureNotSupportedException - if the JDBC driver does not support
this method

Since:

1.2

寄与心 2024-07-13 16:22:16

最简单的方法是运行 Count(*) 查询,执行 resultSet.next() 指向第一行,然后执行 resultSet.getString(1) 来获取计数。 代码 :

ResultSet rs = statement.executeQuery("Select Count(*) from your_db");
if(rs.next()) {
   int count = rs.getString(1).toInt()
}

Easiest approach, Run Count(*) query, do resultSet.next() to point to the first row and then just do resultSet.getString(1) to get the count. Code :

ResultSet rs = statement.executeQuery("Select Count(*) from your_db");
if(rs.next()) {
   int count = rs.getString(1).toInt()
}
好多鱼好多余 2024-07-13 16:22:16

我在这里看到的评论有点过于手动,所以我碰巧遇到了一个更简单的答案。 希望这可以帮助。

resultSet.getFetchSize();

它返回执行查询后获得的所有数据的 int 值。

The comments I can see here are somewhat too manual and I so happen to come across a simpler answer. Hope this helps.

resultSet.getFetchSize();

It returns an int of all the data you got after executing the query.

风筝在阴天搁浅。 2024-07-13 16:22:16

给列一个名称。

String query = "SELECT COUNT(*) as count FROM

将该列从 ResultSet 对象引用到一个 int 中,并从那里执行您的逻辑。

PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, item.getProductId());
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
    int count = resultSet.getInt("count");
    if (count >= 1) {
        System.out.println("Product ID already exists.");
    } else {
        System.out.println("New Product ID.");
    }
}

Give column a name..

String query = "SELECT COUNT(*) as count FROM

Reference that column from the ResultSet object into an int and do your logic from there..

PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, item.getProductId());
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
    int count = resultSet.getInt("count");
    if (count >= 1) {
        System.out.println("Product ID already exists.");
    } else {
        System.out.println("New Product ID.");
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文