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));
}
Related
I am having some trouble figuring out a query that will update values in a column in one of my tables. Below is my function:
public void increasePrice(String [] str) {
PreparedStatement ps = null;
try {
ps = connection.prepareStatement("Update Journey Set price+=? where distance <?",PreparedStatement.RETURN_GENERATED_KEYS);
ps.setDouble(1,Double.parseDouble(str[1]));
ps.setDouble(2, Double.parseDouble(str[0]));
ps.executeUpdate();
ps.close();
System.out.println("1 rows updated.");
} catch (SQLException ex) {
Logger.getLogger(Jdbc.class.getName()).log(Level.SEVERE, null, ex);
}
}
To illustrate, the array passed in contains a value for distance and price and I am wanting to update the prices in the 'Journey' table based on their distance. For example, if a record in the table has a distance (type double) that is less than a given distance (the value of str[0]), I want to increase the price (also a double) of that record by the value 'str[1]' and do this for all records in the table.
The above code doesn't give any errors however, the records in the database never get updated. I could really use some help with this as I've searched around for a while now to try and find a solution and have not yet succeeded.
I do not know what database you are using but my guess is that this line:
ps = connection.prepareStatement("Update Journey Set price+=? where distance <?",PreparedStatement.RETURN_GENERATED_KEYS);
should be written like this:
ps = connection.prepareStatement("Update Journey Set price=price+? where distance <?",PreparedStatement.RETURN_GENERATED_KEYS);
And not related to your question but the line
System.out.println("1 rows updated.");
may make you waste hours of debugging in the future because 0 or more rows can be actually updated.
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.
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.
This question already has answers here:
PSQLException: ResultSet not positioned properly, perhaps you need to call next
(4 answers)
Closed 3 years ago.
Hi I have problem with this code as it seems to always return the SQL Exception. It was working for a few goes then stopped and came back with exception. so I'm not sure what's wrong.
I have tried to change the vld.close() to different places before so yeah. Thanks
PreparedStatement vld = conn.prepareStatement("SELECT * FROM carsharing.available(?,?,?,?)");
vld.setString(1, carName);
vld.setString(2, memberUser);
vld.setTimestamp(3, new java.sql.Timestamp(startTime.getTime()));
vld.setTimestamp(4, new java.sql.Timestamp(endTime.getTime()));
System.out.println("test1");
ResultSet rset = vld.executeQuery();
System.out.println("test2");
rset.next();
int num = rset.getInt("num");
boolean valid = rset.getBoolean("aval");
vld.close();
System.out.println(num);
System.out.println(valid);
1) Verify SQL
Can you verify first that the SQL is correct? It doesn't look correct to me. What you now try to execute is the following SQL:
SELECT * FROM carsharing.available(?,?,?,?)
If you want to limit the resultset by the given name, user and timestamps SQL should look like:
SELECT * FROM carsharing WHERE carNameField=? AND memberUserField=? AND tsField1=? AND tsField2=?
Where you would replace the Field names with the correct column names for your schema.
2) Resultset navigation
Then when you have your resultset after execution you can use first() to navigate to the first position and it also returns boolean so you can check if there even are results available. If you want more values fetched you'll need a loop.
//...
ResultSet rset = vld.executeQuery();
if( rset.first()){
int num = rset.getInt("num");
boolean valid = rset.getBoolean("aval");
}
//...
U need to iterate the result set. U just can't as
rset.next();
The code is
ResultSet rset = vld.executeQuery();
System.out.println("test2");
while(rset.next()) {
int num = rset.getInt("num");
boolean valid = rset.getBoolean("aval");
System.out.println(num);
System.out.println(valid);
}
vld.close();
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();
}
}