I use the below approach to determine my result set is not empty and proceed to do assertions on the values.
...
resultSet = statement.executeQuery("select count(*) as rowCount from tbName where...");
while (resultSet.next()) {
rowCount = Integer.parseInt(resultSet.getString("rowCount"));
}
Assert.assertTrue(rowCount > 0);
resultSet = statement.executeQuery("select * from tbName where ...");
while (resultSet.next()) {
//do some assertions on values here.
}
...
Is there anyway to get the number of rows directly from the resultSet directly in a single query? Something like the below?
resultSet = statement.executeQuery("select * from tbName where ...");
if( resultSet.count/length/size > 0) {
}
You can change the query to include a column with the row count:
select t.*, count(*) over () as row_count
from tbName t
where ...
then you can get the count using
int rowCount rs.getInt("row_count");
Note that you won't get a 0 count because that means the actual query did not return anything in the first place. So you can't use that to verify if your query returned anything. If you only want to check if the result is empty, use next()
resultSet = statement.executeQuery(".....");
if (resultSet.next()) {
// at least one row returned
} else {
// no rows returned at all
}
Btw: you should always use the getXXX() method that matches the column's data type. Using getString() on all columns is not a good idea.
1) Moves the cursor to the last row: resultset.last();
2)Retrieves the current row number: int count = resultset.getRow();
Tips:
It's based on you create a statement via calling function "
Statement createStatement(int resultSetType,int resultSetConcurrency)
throws SQLException"
to gernerate a scrollable resultSet.
There are two ways to get number of rows.
1) if you want to check the number of rows exist in table you may use count query.
2) if you want to count number of rows in a result set you have to traverse that result set to count rows.
Related
I really can't find a solution for this problem:
Here I have two ResultSets, one which always shows me the number of items stored in my database and one that retrieves all the data from it.
I would like to generate a random number and then generate a random item based on the row number/id in my database. Since I'm fairly new I'm not sure if this is an efficient approach. It doesn't look very clean to retrieve all the data and then iterate over it every time. Especially if I had like 1000 items and the randomly generated number is 999.
PreparedStatement randomSelection = con.prepareStatement("SELECT * FROM items ORDER BY RAND() LIMIT 1"); {
String name = ((ResultSet) randomSelection).getString(2);
System.out.println(name);
}
Tried calling the column itemname with the last line. However I just can't look for a good solution for this problem. Would highly appreciate any help since I'm fairly new to databases.
Thank you
EDIT: This is what I tried now and there is no output somehow
Same for
ResultSet numberOfItemsInDataBase = stmt.executeQuery("SELECT count(*) FROM items;");
// this will return a number between 0 and the number of rows - 1
int id = new Random().nextInt(numberOfItemsInDataBase.getInt(1));
ResultSet itemsInDataBase = stmt.executeQuery("select * from items order by id limit 1 offset " + id);
if (itemsInDataBase.next()) {
String item = itemsInDataBase.getString(2);
System.out.println(item);
}
If you just need a random row of the table then you can do it with plain SQL with the function RAND():
ResultSet itemsInDataBase = stmt.executeQuery("select * from items order by rand() limit 1");
if (itemsInDataBase.next()) {
item = new Item(itemsInDataBase.getString(2));
}
If you want to use the generated random number, then use it in the OFFSET clause of the sql statement:
ResultSet numberOfItemsInDataBase = stmt.executeQuery("SELECT count(*) FROM items;");
// the above query will return exactly 1 row
numberOfItemsInDataBase.next();
// this will return a number between 0 and the number of rows - 1
int id = new Random().nextInt(numberOfItemsInDataBase.getInt(1));
ResultSet itemsInDataBase = stmt.executeQuery("select * from items order by id limit 1 offset " + id);
if (itemsInDataBase.next()) {
item = new Item(itemsInDataBase.getString(2));
}
Use ORDER BY RAND() and limit the result to 1. This circumvents you having to query for the count and then ultimately iterate through the ResultSet until you find the random entry.
try (ResultSet randomSelection = connection
.preparedStatement("SELECT * FROM items ORDER BY RAND() LIMIT 1")) {
if (randomSelection.next()) {
String name = randomSelection.getString(2);
}
}
You can use the limit function to get the item.
The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments, which must both be nonnegative integer constants (except when using prepared statements).
With two arguments, the first argument specifies the offset of the first row to return, and the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1). So in your case the offset can be the the random generated id minus one and maximum number of rows is 1:
select * from items LIMIT {id-1},1; # Retrieve row (id-1)
My sql query consists of 5 part which are highly connected to each other. First part creates a temporary table, second part uses that temporary table and creates another temporary table, third part uses the temporary table that created in second part and again creates another temporary table. And the 4th part select some data from 3rd temporary table and 5th part selects the count of 3th temporary table.
Since temporary tables are only usable within a preparedStatement (what I mean is that a temporary table which created by a preparedStatement are not usable from another preparedStatement, I tried that before it is okey) I need to do that within a prepare statement.
So the first 3 part creates temporary tables because of that after setting the parameters to preparedStatement I run preparedStatement.execute() 3 times(I also tried 1....x times) and then I run the preparedStatement.execute() but it returns false which means that there is no resultset. Why is that?
PreparedStatement preparedStatement = conn.prepareStatement("select * into #tmp from tablex where ...\n" +
" select * into #tmp2 from #tmp where ...\n" +
" select * into #tmp3 from #tmp2 where ...\n" +
" select * from #tmp3\n" +
" select count(*) from #tmp3");
Above, I added a simple illustration. Here I need to get the result of 4th and 5th query with prepared statement. How can I do that?
The statements you're executing produce the following results:
An update count
An update count
An update count
A result set
A result set
The meaning of the boolean false returned by execute(String) is:
true if the first result is a ResultSet object; false if it is
an update count or there are no results
This means that you need to use getUpdateCount() to obtain the (first) update count, and getMoreResults() to get the next result (again, this returns a boolean with the same meaning). Only if execute() or getMoreResults() returns false and getUpdateCount() returns -1 are there no more results.
You need to do something like:
boolean nextResultSet = statement.execute(...);
int resultSetCount = 0;
while (true) {
if (nextResultSet) {
resultSetCount++;
try (ResultSet rs = statement.getResultSet()) {
// Do something with result set
}
} else {
int updateCount = statement.getUpdateCount();
if (updateCount == -1) {
// no more results
break;
}
// do something with update count
}
nextResultSet = statement.getMoreResults();
}
You can probably skip part of this complexity by adding SET NOCOUNT ON as the first statement you execute; then you'll not get the update counts and only need to handle the two result sets.
I've had a look around on the web but can't seem to find a definite answer to my question.
Basically, I have a database and table that are successfully working. Now I want to read each line from my table one by one and store the result into a array and I am trying to use a for loop to be more professional rather then using repetition.
I have this code
for (int i=1; i<=8; i++)
{
String query = "Select * FROM Table1 WHERE ID = i";
Rs = St.executeQuery(query);
COL1Title[i] = Rs.getString("CO1Name");
COL2Age[i] = Rs.getString("CO2Rating");
}
The for loop is in a try catch statement and it's complaining with the error "Unknown column 'i' in 'where clause'"
Im guessing there's a certain way for how variable i is to be inserted in the the query.
I should point out ID is a column that has the auto increment feature added on and is primary key if that helps
Could anyone help me out here?
First, we can simplify the task be executing a single query. Note the addition of the range limit and the ORDER BY - without an ORDER BY the results have an unspecified order!
PreparedStatement stmt = "Select ID, CO1Name, CO2Rating"
+ " FROM Table1"
+ " WHERE ID >= ? AND ID <= ?"
+ " ORDER BY ID";
And bind in placeholders (unless there is good reason otherwise, always use placeholders when injecting data into a query). The values could have been hard-coded above in this case, just as they are hard-coded in the for-loop, but the binding is shown here for future reference:
stmt.setInt(1, 1);
stmt.setInt(2, 8);
Then execute the query:
ResultSet rs = stmt.executeQuery();
And iterate the results. Note that rs.next() must be invoke once before any column is read (the cursor starts before any records) and, in this case, it makes it easy to handle a bunch of results.
while (rs.next()) {
int id = rs.getInt("ID");
String title = rs.getString("CO1Name");
String name = rs.getString("CO2Rating");
// do stuff with this record
}
Note that even though the ORDER BY guarantees that the results are iterated in order of ID, assuming a database cardinality rule ensures each result has a unique ID, there may be 0 to 8 records returned - that is, non-existent records may need to be detected/handled separately.
Also (but not shown), make sure to cleanup (close) the ResultSet when done: use a try/finally or try-with-resources construct.
You need to pass i in string as integer, Replace line by:
String query = String.format("Select * FROM Table1 WHERE ID = %d",i);
In a few answers here on SO there is recommended to use ResultSet's function getRow() in order to get the number of entries in a query result. However, following code
private static int getSizeOfResultSet(ResultSet result) throws SQLException{
if(result != null){
int count = 0;
while(result.next()){
count++;
}
System.out.println("Count of resultset is " + result.getRow() + " and count " + count);
return result.getRow();
}else{
System.out.println("Result is null");
return 0;
}
}
is returning me things like
Count of resultset is 0 and count 1
when there is assured that entries are existing (in a JUnit test case). Note that this project has to be in Java6-standard, so maybe this is the issue. Is there anything to consider using the getRow() function?
Additionally, I tried with
result.last();
int c = result.getRow();
result.beforeFirst();
return c;
like mentioned here, but the result is still 0.
EDIT: I should mention that the while(result.next())-loop is for testing purpose. The behaviour without the loop is exactly the same (i.e. 0).
The javadoc states
returns the current row number; 0 if there is no current row
After you've visited all the rows with ResultSet#next() there is no current row.
Use your count value for the number of rows. Or use a SELECT count(*) ... style query.
public int countBookings() throws SQLException{
ResultSet rs=null;
PMDBController db=new PMDBController();
int rowCount=0;
db.getConnection();
String dbQuery="SELECT COUNT(User) AS UserCount FROM INSTRUCTORBOOKING WHERE USER ='"+instructorId+"'";
rs=db.readRequest(dbQuery);
try{
if(rs.next()){
instructorId=rs.getString("UserCount");
}
}catch(Exception e){
e.printStackTrace();
}
rs.last();
rowCount=rs.getRow();
db.terminate();
return rowCount;
}
Basically what this method is supposed to do is count the number of rows gotten from the database. However, it always returns 1 no matter what is inside. Help!
It seems you have a problem in your query. Since you only select 1 user you will always get a count of 1.
"SELECT COUNT(User) AS UserCount FROM INSTRUCTORBOOKING WHERE USER ='"+instructorId+"'"
Try removing your WHERE clause? Maybe that's not exactly what you want, but we can't see your data model from just one query.
rowCount = rs.getInt("UserCount"); instead of instructorId = rs.getString("UserCount"); would do the trick. Or in other words --- you read the number of rows but into variable instructorId.
The number of rows will always be 1. It's the count i.e. the value of that row you need to look at as your query is designed to return the count of rows and not the actual rows.
SELECT COUNT(User) AS UserCount FROM INSTRUCTORBOOKING WHERE USER ='"+instructorId+"'"
You have wrongly interpreted that the number of rows would be the count you are looking for.