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.
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)
Resultset rs=stmt.executeQuery("select count(*) from feedsca group by score order by score");
Using the above java code above, am retrieving the counts of rows from the table named feedsCA.
While trying to retrieving the counts using rs.getInt(1),rs.getInt(2),rs.getInt(3), I end with an error saying as below,
Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: The result set has no current row.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.verifyResultSetHasCurrentRow(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getterGetColumn(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getInt(Unknown Source)
at SimpleMail.main(SimpleMail.java:151)
UPDATE:
The above exception has been resolved.
But I get the following exception, for which I dont know the reason. Please advise.
Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: The index 2 is out of range.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.verifyValidColumnIndex(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getterGetColumn(Unknown Source)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getInt(Unknown Source)
at SimpleMail.main(SimpleMail.java:152)
This is how I have updated my program. Find me a logical way as I can understand well that the loop below will not work as required.
rs=stmt.executeQuery("select count(*) from feedsca group by score order by score");
while(rs.next()){
pw.printf(rowFormat, rs.getLong(1),"0",rs.getLong(2),rs.getLong(3));}
You have to move the cursor of the result set to a row - either by resultSet.first() or by resultSet.next(). Initially the cursor is pointing before the first row, hence your exception.
When you want to iterate the ResultSet:
while(rs.next()) {
...
}
Update: For your second problem - (as noted by Casablanca) your query seems to return only one column, and you are asking for a 2nd and 3rd - and they are not found. Note that in rs.getX(idx) idx is the column, not the row.
You need to call rs.next() before accessing the first row.
Typically, you will iterate over the result set like this:
ResultSet rs = ...;
while (rs.next()) {
...
}
Update: Note that SELECT COUNT(*) ... returns only one field per row, which is the count. You may have several rows, but each row will have only one field, which has index 1. You need to iterate through the rows to get all the counts:
while (rs.next()) {
System.out.println(rs.getInt(1));
}
Yet another update: It's bad to assume that your query will always return only 3 rows. However, if you are absolutely sure of this, then you can just call next 3 times manually:
long l1, l2, l3;
rs.next();
l1 = rs.getLong(1);
rs.next();
l2 = rs.getLong(1);
rs.next();
l3 = rs.getLong(1);
pw.printf(rowFormat, l1,"0",l2,l3);
You need to use one of the methods to move the ResultSet cursor to a row before using the getxxx methods. i.e. rs.next(), rs.first() or rs.last(). These methods return true if a valid row has been located so a typical pattern is
if (rs.first()) {
int field1 = rs.getInt(1);
// other columns
}
or for a query that returns multiple rows:
while (rs.next()) {
int field1 = rs.getInt(1);
// other columns
}
As far as my knowledge, your query will only get one row and column i.e., the total number of rows that your query returns.
Say for example :
Select count(*) from emp;
Generally this query will return a value 14.
so your java code
if(rs.next())
rs.getInt(1);
will return only one value i.e., 14
So, How can you access rs.getString(2). This will automatically throws an exception which you got in the second case.
I'm making a program and I have to get the number of rows in a MySQL database. My table has 4 rows but for some reason I'm getting the number 1 everytime I run the program. Here is my code:
public static void showItems() throws Exception {
try{
Connection con = getConnection();
Statement search = con.createStatement();
ResultSet rs = search.executeQuery("SELECT COUNT(id) FROM main;");
int rows = 0;
rs.beforeFirst();
while (rs.next()){
rows++;
}
System.out.println(rows);
Can someone help me? What am I doing wrong here?
I tried many different ways and none returns me the correct value.
Thanks in advance!
Your query returns one row and contains the value 4 (the count of the number of rows in the table).
Run your query directly in a database client and look at what you get.
This bit of code should show you how to get ahold of the "4". Try this loop in place of the one that contains "row++":
while (rs.next()) {
System.out.println(rs.getInt(1));
}
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.
This is the code I am working on:
if(connection.doDatabaseRead(findSQL))
{
ResultSet retRES = connection.getResultSet();
int i = 0;
// did we find anything
while( retRES.next() )
{
//read result from query
suiteNum.add(retRES.getString(i)); // this is the problem
i++;
//let other threads breathe
Thread.yield();
}
}
suiteNum is a string vector
When I try to add the database results to the vector the code crashes with this error.
java.sql.SQLException: Column Index out of range, 0 > 1.
I have the same piece of code working elsewhere in the program but I use real numbers like 0, 1 and 2 instead of i and it works fine.
As I do not know how many results the database request will have I need it to be dynamic but it will only work hard coded.
How can I make it work with i ?
The argument to getString is the column index, not the row index as you seem to think. The function returns the value of the given column in the current row, while next advances the cursor to the next row.
You probably mean:
suiteNum.add(retRES.getString(1));
in which case you can lose i altogether.
Java ResultSet objects are 1-indexed in this regard. The first element is at 1, not 0. See the javadoc.
EDIT: That's true too, but indeed the problem is this appears to be used as a row index! it's certainly the column.
This is your problem:
i = 0;
...
retRES.getString(i);
ResultSet.getString(i) gets a String from column number i
You want something like
while(retRes.next()) {
add(retRes.getString(1);
}
column index starts from 1
As I do not know how many results the database request will have I need it to be dynamic but it will only work hard coded. How can I make it work with i
ResultSetMetaData rsMetaData = rs.getMetaData();
int numberOfColumns = rsMetaData.getColumnCount();
See Also
ResultSetMetaData
Let your i start with 1 as specified in the API docs
if(connection.doDatabaseRead(findSQL))
{
ResultSet retRES = connection.getResultSet();
int i = 1;
// did we find anything
while( retRES.next() )
{
//read result from query
suiteNum.add(retRES.getString(i)); // this is the problem
i++;
//let other threads breathe
Thread.yield();
}
}