This question already has answers here:
ResultSet exception - before start of result set
(6 answers)
Closed 6 years ago.
I'm getting java.sql.SQLException: Before start of result set when I try to use this code:
ResultSet user = query("SELECT `id`, `counter` FROM `accounts` WHERE `username`='test'");
int id = user.getInt("id");
int counter = user.getInt("counter");
System.out.println("Id: " + id + " | Counter: " + counter);
All I really need to do is get the values of id and counter and set it to an integer in java but I'm not sure how to do that this is the third method I've tried, is there anything else I can do to get that information? I know for a fact the problem isn't with my query method so I figured it'll be pointless to show it, this is pretty much the entire snippet. (Yes the connection is opened and closed no problem) Any help would be appreciated.
Add a call to user.next(); before trying to read the first row. You are literally before the first row. Typically, you would use a loop like
while (user.next()) {
int id = user.getInt("id");
int counter = user.getInt("counter");
System.out.println("Id: " + id + " | Counter: " + counter);
}
The ResultSet.next() Javadoc says (in part),
A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.
Related
Using Java I want to obtain all IDs from my database and select GW_STATUS if it is equal to 0. I used the following SQL statement to achieve this.
PreparedStatement get_id = con.prepareStatement("SELECT ID from SF_MESSAGES where GW_STATUS = 0");
Once the IDs have been obtained, I want to update GW_STATUS to 1 according to their ID as demonstrated in the code below but only one field is being updated when I execute the code.
PreparedStatement update = con.prepareStatement("update SF_MESSAGES set GW_STATUS=? where ID = ?");
update.setInt(1,1);
ResultSet x = get_id.executeQuery();
while(x.next()){
int uber = x.getInt(1);
int array[] = new int[] {uber};
for (int value : array) {
System.out.println("Value = " + value); //Successfully obtains and prints each ID from the databse table
update.setInt(2,value); // Only one ID is updated therefore only field updated
}
}
int result = update.executeUpdate();
System.out.println(result + " Records updated");
I've tried using another update statement within the for loop to update every ID obtained but that doesn't work too. How can I successfully update every field according to their ID?
You can make the whole processing much simple. It turns out that you just want to update SF_MESSAGES which have GW_STATUS equals to 0, so your query can look like the following:
update SF_MESSAGES set GW_STATUS=1 where GW_STATUS=0
Therefore, you do not have to fetch IDs, loop over them so it is more efficient solution.
Here is my MySql table:
I want to show the output of the query in commandline as below:
I have written the code below to loop but I am getting only the first row, What i have to modify ??
ResultSet rs2 = stmt.executeQuery(table_retrive);
String[] cols = new String[itemList.size()];
int[] rec =new int[itemList.size()];
for (int i = 0; i < itemList.size(); i++) {
while (rs2.next()) {
cols[i] =(String) itemList.get(i);
rec[i] = rs2.getInt(cols[i]);
System.out.println(rec[i]+" ");
}
}
Your two loops are wrong. Start at i=0 and then iterate once over the whole ResultSet, filling yor first array position. When this is done, i is incremented and you try to iterate the ResultSet a second time but the cursor is at the end of the ResultSet, so rs2.next() returns false and the code will not be executed.
So you have two Solutions:
Handle the loops correctly. Unfortunately I do not know, what you are trying to do anyways because this is some C-like code without OOP, which doesn't show semantics and then you have this itemList which seems to hold preset values and you read out of this list, which column to take for the i-th position. This seems odd. Maybe switching the loops does the desired: Start with the while and nest the for.
Reset the cursor of the ResultSet after the while with rs2.beforeFirst(). WARNING: This could throw a SQLFeatureNotSupportedException. Not all Databases can move the cursor backwards. This is of course a very ugly solution, since you should first parse the whole row a once.
Try to use printf() Or format() method. It is same as printf method in c lang. you can pass parameters and difference. Look at link1
And link 2
Example : System.out.printf("%d%5s%10d", 5,"|",10);
output : 5 | 10
Using this the I got all the values but in one row :
while (rs2.next()) {
for (int i = 0; i < itemList.size(); i++) {
cols[i] =(String) itemList.get(i);
rec[i] = rs2.getInt(cols[i]);
System.out.print(rec[i]+" ");
}
}
But I need to divide like the rows.
Usage of the inner loop is your problem.
You can enhance your code to remove the usage of the second loop in your code, it basically does nothing. You can loop over your result set and in the same loop using the incremented variable to persist the values accordingly.
The code shown half implemented in your question, hence it will be difficult to give you exactly what need to be done. Nevertheless, here's an attempt to resolve the problem for you:
while (rs2.next()) {
System.out.println(rs2.getInt(1) + "\t |" + rs2.getString(2) + "\t |" + rs2.getString(3));
}
Based on the column names from the table in the question, assuming that column2 and column3 are String's.
You can add the necessary details to this code to complete it according to your usecase, but I've just taken the example of showing a record in one line.
EDIT:
OP has his own way of programming, but to satisfy his question in the comment - this is how you can do it.
while (rs2.next()) {
for (int i = 0; i < itemList.size(); i++)
{
cols[i] =(String) itemList.get(i);
rec[i] = rs2.getInt(cols[i]);
System.out.print(rec[i]+"\t |");
}
System.out.println();
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have the following peice of code:
Class.forName("oracle.jdbc.driver.Orac. leDriver");
Connectioncon=DriverManager.getCon. nection ("jdbc:oracle:thin:#localhost1521:","sys. tem","zed");
String pb=pricebox.getText();
int pbs=Integer.parseInt(pb);
final PreparedStatement ps=con.prepareStatement("selectitem code,remaining fromshoppingmallproducts wheretype='"+typebox.getSelectedIte(+. "',brand='"+brandbox.getSelectedIt. +'"');
final PreparedStatementps=con.prepareStat. ement("select itemcode,remainingfrom shoppingmallproducts where type=and brand=? and price>=?");
ps.setString(1(String)typebox.getSelect. editem();
ps.setString(2, (String)brandbox.getSelectedItem());
ps.setInt(3,pbs);
final ResultSet rs=ps.executeQuery();
rs.next();
itm=rs.getString("itemcode");
int rem=rs.getInt("remaining");
final String remm=String.valueOf(rem);
jta1.append("\n "+itm+"\n"+rem+"\n");
// jta is the name of the jtextpane used to append data
next.addActionListener(new ActionListener()
{
public void
actionPerformed(ActionEvent as)
{
try {
jta1.removeAll();
jta1.setText("");
rs.next();
String itm=rs.getString("itemcode");
int prc=rs.getInt("price");
int rem=rs.getInt("remaining");
String remm=String.valueOf(rem);
jta1.append("\n "+itm+"\n"+rem. +"\n");
drawimage(itm);
}
Now the question belongs to my next button.
As you can see, the next button will move the result set object to the next row. But I want it to perform it the other way. Now suppose, I choose Levis as brand price range 2000 and type casual shoes. Now suppose I have 3 such products. The first time when I click go button, it will show the first result. Now I want that when I click next, I want the second product with specified features, and so the third product.
Is there any way to do this? Please help me. I am really stuck with this as this is the last task in my college project.
I hope I have clearly explained every thing. Thanx
your question is not very clear. But I shall try to answer from what I understand.
first about rs.next();
This cursor is a pointer that points to one row of data in the ResultSet. Initially, the cursor is positioned before the first row. The method ResultSet.next moves the cursor to the next row. This method returns false if the cursor is positioned after the last row.
So rs.next() points to the result obtained from running your query. Let us say your table has 10 rows in total and then your query return 5 rows from that, depending on the conditions you have specified in the query(like brand,price etc ) . In such a case the rs will point to the 5 rows returned for your query. It will be pointed to before the first row of the result. when you do rs.next(); it should return the first row of the 5 rows returned as result. every rs.next() henceforth will return the next row from the 5 result rows. when rs points to 5th row and you do rs.next() then it will return false and you will know that not more rows exist to be returned.
if you are not getting value in this manner , most probable reason is your query. Try printing out all the rows returned from query using code
while (rs.next()) {
int itm = rs.getString("itemcode");
int price = rs.getString("price");
int remaining = rs.getString("remaining");
System.out.println(itm + "\t" + price +
"\t" + remaining );
}
this will print the result to the console for you to debug.
If this is printing the correct result then your query is correct. May be the problem is that rs value in jtextpane is incorrect and not pointing correctly as it should be.
PS : variable type of price should be double
Also if your question was just about order of returned result you could use ORDER BY with your query. it will allow the result to be returned according to the sorted order (ascending or descending based on a column ) of the table
I have a quick question in regards to the value of how variable values work. I am working on a program right now, which looks like this:
public void run() {
println("There are " + ATOMS + " initially.");
int atoms = ATOMS;
int year = 0;
while (atoms > 0) {
for (int i = atoms; i > 0; i--) {
println(i);
if( rgen.nextBoolean() ) {
atoms--;
println("The total atoms is " + atoms);
}
println("The total for i is " + i + "\n" );
}
year++;
println("There are " + atoms + " at the end of year " + year );
}
}
At the part with the for loop, and setting the variable i to the value of atoms, is what has me confused. Lets say the value of atoms starts at 20. It goes through the for loop and lets assume that the first time through the RandomGenerator makes it true. So that subtracts 1 from atoms. Then after that the value of i should also be minused due to the i--. So my question is: When I set the variable i to the value of atoms does that just take i and set it to the initial value of 20? And then from there every time I adjust the value of i it is taking off of its own version of 20, and then when I change the value of atoms it, too has its own value. So when I subtract from atoms, that is not also being subtracted from i? That is the only way I can make sense of it because this program is written and works correctly, but that part has me confused.
Thank you very much in advance for any help!
yes you have answered your own question. the variable i and atoms are two separate instances.
when you start the loop you are setting i equal to the same value as atoms but they are still separate variables. therefore inside the loop when you change the value of one it does not affect the other.
Once you set the value of i=atoms, it no longer changes. It is the loop initializer, and will no longer be processed.
"i" of course will be decremented continuously (because of the i-- decrement).
But you can change the value of atoms to whatever and the results will not change.
i=atoms is the initialization in the for loop. So then on, value of i independent of atoms.
I want to get the size of the ResultSet inside the while loop.
Tried the code below, and I got the results that I want. But it seems to be messing up with result.next() and the while loop only loops once if I do this.
What's the proper way of doing this?
result.first();
while (result.next()){
System.out.println(result.getString(2));
System.out.println("A. " + result.getString(5) + "\n" + "B. " + result.getString(6) + "\n" + "C. " + result.getString(7) + "\n" + "D. " + result.getString(8));
System.out.println("Answer: ");
answer = inputquiz.next();
result.last();
if (answer.equals(result.getString(10))) {
score++;
System.out.println(score + "/" + result.getRow());
} else {
System.out.println(score + "/" + result.getRow());
}
}
What's the proper way of doing this?
Map it to a List<Entity>. Since your code is far from self-documenting (you're using indexes instead of column names), I can't give a well suited example. So I'll take a Person as example.
First create a javabean class representing whatever a single row contains.
public class Person {
private Long id;
private String firstName;
private String lastName;
private Date dateOfBirth;
// Add/generate c'tors/getters/setters/equals/hashcode and other boilerplate.
}
(a bit decent IDE like Eclipse can autogenerate them)
Then let JDBC do the following job.
List<Person> persons = new ArrayList<Person>();
while (resultSet.next()) {
Person person = new Person();
person.setId(resultSet.getLong("id"));
person.setFirstName(resultSet.getString("fistName"));
person.setLastName(resultSet.getString("lastName"));
person.setDataOfBirth(resultSet.getDate("dateOfBirth"));
persons.add(person);
}
// Close resultSet/statement/connection in finally block.
return persons;
Then you can just do
int size = persons.size();
And then to substitute your code example
for (int i = 0; i < persons.size(); i++) {
Person person = persons.get(i);
System.out.println(person.getFirstName());
int size = persons.size(); // Do with it whatever you want.
}
See also:
How to check if there is zero-or-one result or one-or-more results and their size
you could do result.last(); and call result.getRow(); (which retrieves the current row number) to get count. but it'll have load the all the rows and if it's a big result set, it might not be very efficient. The best way to go about is to do a SELECT COUNT(*) on you query and get the count like it's demonstrated in this post, beforehand.
This is a tricky question.
Normally, result.last() scrolls to the end of the ResultSet, and you can't go back.
If you created the statement using one of the createStatement or prepareStatement methods with a "resultSetType" parameter, and you've set the parameter to ResultSet.TYPE_SCROLL_INSENSITIVE or ResultSet.TYPE_SCROLL_SENSITIVE, then you can scroll the ResultSet using first() or relative() or some other methods.
However, I'm not sure if all databases / JDBC drivers support scrollable result sets, and there are likely to be performance implications in doing this. (A scrollable result set implies that either the database or the JVM needs to buffer the entire resultset somewhere ... or recalculate it ... and that's expensive for a large resultset.)
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();
There are also another way to get the count from DB.
Note :
This column gets updated when DBA'S do realtime statistics
select num_rows from all_Tables where table_name ='<TABLE_NAME>';