So, I want to loop this ResultSet in order to update the table one by one, but the method while(rsl.next()) can't help me do the looping. It's just work once, and then the others are skipped. Can someone help me fix this problem? Thanks in advance
try {
String url = "jdbc:mysql://localhost/minimarket";
String user = "root";
String pass = "";
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, user, pass);
Statement stmt = conn.createStatement();
ResultSet rsl = stmt.executeQuery("SELECT * FROM keranjang WHERE pemesan='"+login.userid+"'");
while (rsl.next()) {
String nb = rsl.getString("nama_barang");
String dtl = rsl.getString("detail");
String beratt = rsl.getString("berat");
String hrga = rsl.getString("harga");
String jmlh = rsl.getString("jumlah");
stmt.executeUpdate("UPDATE barang SET stok=stok+'"+jmlh+"' WHERE nama_barang='"+nb+"' AND detail='"+dtl+"' AND berat='"+beratt+"'");
stmt.executeUpdate("DELETE FROM keranjang WHERE pemesan ='"+login.userid+"' AND nama_barang='"+nb+"'");
}
conn.close();
} catch (Exception error) {
}
System.exit(0);
Problem:
if (rsl.next())
fix:
while (rsl.next())
Debug the app and check if the your connection to the database is valid.
When you execute an executeUpdate on your statement an int is returned and most importantly your result set object rs1 from your query gets closed and can't be accessed anymore since the Statement class only handles one query/result set. I haven't tested this myself but I am pretty sure this is the reason.
The solution is to have a separate Statement object for the update/delete so that the original ResultSet is not affected. Something like below
Statement stmt = conn.createStatement();
Statement updStmt = conn.createStatement();
ResultSet rsl = stmt.executeQuery("SELECT * FROM keranjang WHERE pemesan='"+login.userid+"'");
while (rsl.next()) {
String nb = rsl.getString("nama_barang");
String dtl = rsl.getString("detail");
String beratt = rsl.getString("berat");
String hrga = rsl.getString("harga");
String jmlh = rsl.getString("jumlah");
updStmt.executeUpdate("UPDATE barang SET stok=stok+'"+jmlh+"' WHERE nama_barang='"+nb+"' AND detail='"+dtl+"' AND berat='"+beratt+"'");
updStmt.executeUpdate("DELETE FROM keranjang WHERE pemesan ='"+login.userid+"' AND nama_barang='"+nb+"'");
}
If I've understood your problem correctly, there are two possible problems here:
the resultset is null - I assume that this cant be the case as if it was you'd get an exception in your while loop and nothing would be output
the second problem is that resultset.getString(i++) will get columns 1,2,3 and so on from each subsequent row
I think that the second point is probably your problem here.
Let us say you only had 1 row returned, as follows
Col 1, Col 2, Col3
A , B, C
Your code as it stands would only get A - it wouldn't get the rest of the columns.
I suggest you change your code as follows:
ResultSet resultset = ...;
ArrayList<String> arrayList = new ArrayList<String>();
while (resultset.next()) {
int i = 1;
while(i <= numberOfColumns) {
arrayList.add(resultset.getString(i++));
}
System.out.println(resultset.getString("Col 1"));
System.out.println(resultset.getString("Col 2"));
System.out.println(resultset.getString("Col 3"));
System.out.println(resultset.getString("Col n"));
}
To get the number of columns:
ResultSetMetaData metadata = resultset.getMetaData();
int numberOfColumns = metadata.getColumnCount();
Related
I have a result set which is not empty. It contains 6 columns. But if I want to use the loop, nothing happens.
If I call the stored procedure in SQL Server Management Studio with the same parameters as in the Java code, I got a result:
A few minutes ago everything worked
// That doesn't work because I can't get into the loop
if (con != null) {
String an_id = "bkoubik";
String AS_Aufruf = "exec BfV_Web.sp_Anwender_Start\n#AnwenderID = ?";
try {
PreparedStatement STMT = con.prepareStatement(AS_Aufruf);
STMT.setString(1, an_id);
ResultSet rs = STMT.executeQuery();
//THIS IF STATEMENT IS NOT ENTERING, SO WHY THEN THE WHILE LOOP
IS NOT WORKING ?
if (!rs.next() ) {
System.out.println("no data");
}
ResultSetMetaData meta = rs.getMetaData();
int intRS = meta.getColumnCount();
//THE LOOP IS NOT ENTERING
while (rs.next()) {
[...]
}
intRS is the column count, not the row count. Your rs is likely empty.
The first call to rs.next() (before the loop) already consumes the one and only row, so the next call (in the while) will return false.
I am using a mysql table, and now I need to compare a columns all values with a given String.
I want to check if all values of the result set matches with encryptedString.
Need to understand what result set does and how it works.
Here I have a method, Some variables, and 2 mysql queries.
final String secretKey = "!!!!";
String name = jText.getText();
String pass = jTextPass.getText();
String originalString = pass;
String encryptedString = AES.encrypt(originalString, secretKey) ;
String decryptedString = AES.decrypt(encryptedString, secretKey) ;
PreparedStatement PS;
ResultSet result;
String query1 = "SELECT `pass` FROM `Remember_Pass` WHERE `name` =?";
PreparedStatement ps;
String query;
query = "UPDATE `tutor profile` SET `pass`=? WHERE `name`=?";
try {
PS = MyConnection.getConnection().prepareStatement(query1);
PS.setString(1, name);
PS.setString(2, encryptedString);
rs = PS.executeQuery();
//while(result.next() ){
//I am not understanding what to do here.
ps = MyConnection.getConnection().prepareStatement(query);
ps.setString(1, encryptedString);
ps.setString(2, name);
ps.executeUpdate();
PassSuccess success = new PassSuccess();
success.setVisible(true);
success.pack();
success.setLocationRelativeTo(null);
this.dispose();
//}
} catch (SQLException ex) {
Logger.getLogger(ForgetPassT.class.getName()).log(Level.SEVERE, null, ex);
}
First tip: using try-with-resources closes statement and result set even on exception or return. This also reduces the number of variable names for them because of the smaller scopes. This return from the innermost block I utilized. For unique names one can use if-next instead of while-next. A fail-fast by not just logging the exception is indeed also better; you can exchange the checked exception with a runtime exception as below, so it easier on coding.
String query1 = "SELECT `pass` FROM `Remember_Pass` WHERE `name` = ?";
String query = "UPDATE `tutor profile` SET `pass`=? WHERE `name`= ?";
try (PreparedStatement selectPS = MyConnection.getConnection().prepareStatement(query1)) {}
selectPS.setString(1, name);
//selectPS.setString(2, encryptedString);
try (ResultSet rs = selectPS.executeQuery()) {}
if (result.next()){ // Assuming `name` is unique.
String pass = rs.getString(1);
try (PreparedStatement ps = MyConnection.getConnection().prepareStatement(query)) {
ps.setString(1, encryptedString);
ps.setString(2, name);
int updateCount = ps.executeUpdate();
if (updateCount == 1) {
PassSuccess success = new PassSuccess();
success.setVisible(true);
success.pack();
success.setLocationRelativeTo(null);
return success;
}
}
}
}
} catch (SQLException ex) {
Logger.getLogger(ForgetPassT.class.getName()).log(Level.SEVERE, null, ex);
throw new IllegalStateException(e);
} finally {
dispose();
}
the ResultSet object contains all the information about the query that you perform, it will contain all columns. In your code the result variable will return anything since there is no part in your code where is executed, to do this you have to...
Statement statement = MyConnection.getConnection().createStatement();
ResultSet result = statement.executeQuery("YOUR SELECT STATEMENT HERE");
while(result.next()){
String column1 = result.getString("columnName");
}
The result.next() method is a boolean method that says if the ResultSet object still have values of the table inside and it will continue until it reaches the last row that your SELECT statement retrives. Now if you want to match the value of some column with other variables you can do it inside the while(result.next()).
result.getString("columnName") will extract the value from columnName as a String.
If you want to save things in an ArrayList to save the data and then use this list as you want the code can be like...:
Statement statement = MyConnection.getConnection().createStatement();
ResultSet result = statement.executeQuery("YOUR SELECT STATEMENT HERE");
List<Object> data = new ArrayList();
while(result.next()){
data.add(result.getString("columnName"));
}
return data;
Obviously you have to change the Object with the type of things that you want to store in the List.
Or if you want to store the data in an array. As I said in my comment this won't be dinamic, but...:
Statement statement = MyConnection.getConnection().createStatement();
ResultSet result = statement.executeQuery("YOUR SELECT STATEMENT HERE");
String[] data = new String[NUMBER_OF_COLUMNS_IN_RESULTSET];
while(result.next()){
data[0] = result.getString("columnName1");
data[1] = result.getString("columnName2");
data[2] = result.getString("columnName3");
//And so on...
}
return data;
The other way is that if you are returning an entity you can set the values of the ResultSet directly in the POJO:
Statement statement = MyConnection.getConnection().createStatement();
ResultSet result = statement.executeQuery("YOUR SELECT STATEMENT HERE");
Entity entity = new Entity();
while(result.next()){
entity.setColumnName1(result.getString("columnName1"));
entity.setColumnName2(result.getString("columnName2"));
entity.setColumnName3(result.getString("columnName3"));
//And so on...
}
return entity;
There are so many ways to store the data, just ask yourself how do you want to receive the data in the other parts of you code.
Regards.
I'm having a really bad time with a ResultSet, which is closed within a while-Loop for iterating this ResultSet. I have know the exact line in which the ResultSet is closed, but i have no idea why.
public LinkedList<Athlet> alleAbrufen () throws SQLException {
LinkedList<Athlet> alleAthleten = new LinkedList<Athlet>();
String abrufenAthleten = "SELECT * FROM Athlet ORDER BY athlet_id";
ResultSet athleten_rs = stmt.executeQuery(abrufenAthleten);
while (athleten_rs.next()) {
long id = athleten_rs.getInt(1);
String name = athleten_rs.getString(2);
LinkedList<Leistung> alleLeistungen = alleAbrufen((int) (id)); //after this line the ResultSet gets closed
alleAthleten.add(new Athlet(id, name, alleLeistungen));
}
return alleAthleten;
}
public LinkedList<Leistung> alleAbrufen(int athlet_id) throws SQLException {
LinkedList<Leistung> alleLeistungen = new LinkedList<Leistung>();
String selectLeistungen = "SELECT * FROM Leistung WHERE athlet_id="+athlet_id;
ResultSet rs = stmt.executeQuery(selectLeistungen);
while (rs.next()) {
long id = rs.getInt(1);
String bezeichnung = rs.getString(2);
String datum = rs.getString(3);
double geschwindigkeit = rs.getDouble(4);
boolean selectedForSlopeFaktor = rs.getBoolean(5);
int strecke_id = rs.getInt(7);
long longAthlet_id = (long) athlet_id;
Leistung leistung = new Leistung(strecke_id, longAthlet_id, bezeichnung, datum, geschwindigkeit);
leistung.setLeistungID(id);
leistung.setIsUsedForSlopeFaktor(selectedForSlopeFaktor);
alleLeistungen.add(leistung);
}
return alleLeistungen;
}
I marked the line after which the ResultSet is closed with a comment. Alle other methods, constructors, etc used in the above example are tested an working properly. Does anyone have a clue why calling the second method closes the ResultSet in the first method?
The problem is that the Statement can only maintain a single group of ResultSets per executed statement. Since you share the same Statement stmt for your two methods, in alleAbrufen the Statement executes another statement, which will break the reference to the prior ResultSet.
The best solution for this case is to create a Statement per statement execution. This is, every method should contain its unique Statement and related ResultSets.
public LinkedList<Athlet> alleAbrufen () throws SQLException {
LinkedList<Athlet> alleAthleten = new LinkedList<Athlet>();
String abrufenAthleten = "SELECT * FROM Athlet ORDER BY athlet_id";
//here
Statement stmtAlleAbrufen = con.createStatement();
ResultSet athleten_rs = stmtAlleAbrufen.executeQuery(abrufenAthleten);
while (athleten_rs.next()) {
long id = athleten_rs.getInt(1);
String name = athleten_rs.getString(2);
LinkedList<Leistung> alleLeistungen = alleAbrufen((int) (id)); //after this line the ResultSet gets closed
alleAthleten.add(new Athlet(id, name, alleLeistungen));
}
return alleAthleten;
}
public LinkedList<Leistung> alleAbrufen(int athlet_id) throws SQLException {
LinkedList<Leistung> alleLeistungen = new LinkedList<Leistung>();
//here again, but since you need to use parameters in your query
//use PreparedStatement instead
//note that I commented the current query
//String selectLeistungen = "SELECT * FROM Leistung WHERE athlet_id="+athlet_id;
//this is how a query with parameters look like
String selectLeistungen = "SELECT * FROM Leistung WHERE athlet_id=?";
//the connection prepares the statement
PreparedStatement pstmt = con.prepareStatement(selectLeistungen);
//then we pass the parameters
pstmt.setInt(1, athlet_id);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
long id = rs.getInt(1);
String bezeichnung = rs.getString(2);
String datum = rs.getString(3);
double geschwindigkeit = rs.getDouble(4);
boolean selectedForSlopeFaktor = rs.getBoolean(5);
int strecke_id = rs.getInt(7);
long longAthlet_id = (long) athlet_id;
Leistung leistung = new Leistung(strecke_id, longAthlet_id, bezeichnung, datum, geschwindigkeit);
leistung.setLeistungID(id);
leistung.setIsUsedForSlopeFaktor(selectedForSlopeFaktor);
alleLeistungen.add(leistung);
}
return alleLeistungen;
}
Don't forget to close the resources, Statement and ResultSet, after using them.
Your problem's answer comes from the javadoc:
By default, only one ResultSet object per Statement object can be open
at the same time. Therefore, if the reading of one ResultSet object is
interleaved with the reading of another, each must have been generated
by different Statement objects.
Is your Statement a class variable and you are using the same for both the queries? Is yes, it's wrong. You can have only one ResultSet per Statement.
See the java docs.
I'm having a really bad time with a ResultSet, which is closed within a while-Loop for iterating this ResultSet. I have know the exact line in which the ResultSet is closed, but i have no idea why.
public LinkedList<Athlet> alleAbrufen () throws SQLException {
LinkedList<Athlet> alleAthleten = new LinkedList<Athlet>();
String abrufenAthleten = "SELECT * FROM Athlet ORDER BY athlet_id";
ResultSet athleten_rs = stmt.executeQuery(abrufenAthleten);
while (athleten_rs.next()) {
long id = athleten_rs.getInt(1);
String name = athleten_rs.getString(2);
LinkedList<Leistung> alleLeistungen = alleAbrufen((int) (id)); //after this line the ResultSet gets closed
alleAthleten.add(new Athlet(id, name, alleLeistungen));
}
return alleAthleten;
}
public LinkedList<Leistung> alleAbrufen(int athlet_id) throws SQLException {
LinkedList<Leistung> alleLeistungen = new LinkedList<Leistung>();
String selectLeistungen = "SELECT * FROM Leistung WHERE athlet_id="+athlet_id;
ResultSet rs = stmt.executeQuery(selectLeistungen);
while (rs.next()) {
long id = rs.getInt(1);
String bezeichnung = rs.getString(2);
String datum = rs.getString(3);
double geschwindigkeit = rs.getDouble(4);
boolean selectedForSlopeFaktor = rs.getBoolean(5);
int strecke_id = rs.getInt(7);
long longAthlet_id = (long) athlet_id;
Leistung leistung = new Leistung(strecke_id, longAthlet_id, bezeichnung, datum, geschwindigkeit);
leistung.setLeistungID(id);
leistung.setIsUsedForSlopeFaktor(selectedForSlopeFaktor);
alleLeistungen.add(leistung);
}
return alleLeistungen;
}
I marked the line after which the ResultSet is closed with a comment. Alle other methods, constructors, etc used in the above example are tested an working properly. Does anyone have a clue why calling the second method closes the ResultSet in the first method?
The problem is that the Statement can only maintain a single group of ResultSets per executed statement. Since you share the same Statement stmt for your two methods, in alleAbrufen the Statement executes another statement, which will break the reference to the prior ResultSet.
The best solution for this case is to create a Statement per statement execution. This is, every method should contain its unique Statement and related ResultSets.
public LinkedList<Athlet> alleAbrufen () throws SQLException {
LinkedList<Athlet> alleAthleten = new LinkedList<Athlet>();
String abrufenAthleten = "SELECT * FROM Athlet ORDER BY athlet_id";
//here
Statement stmtAlleAbrufen = con.createStatement();
ResultSet athleten_rs = stmtAlleAbrufen.executeQuery(abrufenAthleten);
while (athleten_rs.next()) {
long id = athleten_rs.getInt(1);
String name = athleten_rs.getString(2);
LinkedList<Leistung> alleLeistungen = alleAbrufen((int) (id)); //after this line the ResultSet gets closed
alleAthleten.add(new Athlet(id, name, alleLeistungen));
}
return alleAthleten;
}
public LinkedList<Leistung> alleAbrufen(int athlet_id) throws SQLException {
LinkedList<Leistung> alleLeistungen = new LinkedList<Leistung>();
//here again, but since you need to use parameters in your query
//use PreparedStatement instead
//note that I commented the current query
//String selectLeistungen = "SELECT * FROM Leistung WHERE athlet_id="+athlet_id;
//this is how a query with parameters look like
String selectLeistungen = "SELECT * FROM Leistung WHERE athlet_id=?";
//the connection prepares the statement
PreparedStatement pstmt = con.prepareStatement(selectLeistungen);
//then we pass the parameters
pstmt.setInt(1, athlet_id);
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
long id = rs.getInt(1);
String bezeichnung = rs.getString(2);
String datum = rs.getString(3);
double geschwindigkeit = rs.getDouble(4);
boolean selectedForSlopeFaktor = rs.getBoolean(5);
int strecke_id = rs.getInt(7);
long longAthlet_id = (long) athlet_id;
Leistung leistung = new Leistung(strecke_id, longAthlet_id, bezeichnung, datum, geschwindigkeit);
leistung.setLeistungID(id);
leistung.setIsUsedForSlopeFaktor(selectedForSlopeFaktor);
alleLeistungen.add(leistung);
}
return alleLeistungen;
}
Don't forget to close the resources, Statement and ResultSet, after using them.
Your problem's answer comes from the javadoc:
By default, only one ResultSet object per Statement object can be open
at the same time. Therefore, if the reading of one ResultSet object is
interleaved with the reading of another, each must have been generated
by different Statement objects.
Is your Statement a class variable and you are using the same for both the queries? Is yes, it's wrong. You can have only one ResultSet per Statement.
See the java docs.
private void btgetinvActionPerformed(java.awt.event.ActionEvent evt) {
//JOptionPane.showMessageDialog(null, "REMITTANCE ID IS VALID!");
try {
DBUtil util = new DBUtil();
Connection con = util.getConnection();
PreparedStatement stmt = con.prepareStatement("select bk_det.rm_id from bk_det WHERE dbo.bk_det.rm_id = ?");
ResultSet rs;
String rm = tf_rmid.getText().trim();
stmt.setInt(1, Integer.parseInt(rm));
rs = stmt.executeQuery();
while (rs.next()) {
int i = Integer.parseInt(rs.getString("box_no"));
tfbrname.setText(rs.getString(i));
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}
I am actually trying to search value from my database table called dbo.bk_det. I am taking the value of WHERE from my textfield tf_rmid. Everything goes on well without error but once i insert the rm_id and click on button btgetinv it says 123 which is my rm_id is out of range cant understand where the error is and what is the problem.
The problem is with the following statements:
int i = Integer.parseInt(rs.getString("box_no"));
tfbrname.setText(rs.getString(i));
The first statement won't work the way you want because there's no column named "box_no" in the select clause. It will throw an exception. Let's assume you change the code to have box_no in the select clause. Then, the second statement will try to retrieve the nth column where the column is the value of box_no. I think you just want:
tfbrname.setText(rs.getString("box_no"));
Again, the above only will work if your SELECT statement includes box_no in the field list.
rs.next() returns false if it does not contain any more records. So if you want to behave something when no records found, you have to check record count.
for example,
int recordCount = 0;
while (rs.next()) {
recordCount++;
int i = Integer.parseInt(rs.getString("box_no"));
tfbrname.setText(rs.getString(i));
}
if(recordCount == 0) {
// do something : report an error or log
}
for further information, see http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#next()