m trying to loop through 3 resultsets and compare their values. bt its throwing this exception...could someone help me on where am going through?
here is the piece of code:
java.lang.Object[] reconciledPaymentDetails = null;
java.util.Vector shiftsVector = new java.util.Vector(1, 1);
String status = "";
try {
Class.forName("org.postgresql.Driver");
}
catch (ClassNotFoundException ex) {
Logger.getLogger(DBConnection.class.getName()).log(Level.SEVERE, null, ex);
}
try {
connDB = DriverManager.getConnection("jdbc:postgresql://" + hostName + ":" + portNumber + "/" + dbName, userName, password);
System.out.println("Connection established : [" + connDB.toString() + "]");
java.sql.Statement pstmt = connDB.createStatement();
java.sql.Statement pstmtShifts = connDB.createStatement();
java.sql.ResultSet rset = pstmt.executeQuery("SELECT DISTINCT payment_mode,transaction_type, credit FROM ac_cash_collection WHERE shift_no = '" + shiftNumber + "'");
while (rset.next()) {
java.sql.ResultSet rsetShifts = pstmtShifts.executeQuery("SELECT DISTINCT amount, shift_amount FROM ac_shift_collections WHERE shift_no = '" + shiftNumber + "' AND pay_mode ilike '"+rset.getString(1) +"'");
while (rsetShifts.next()) {
java.sql.ResultSet rset2 = pstmt.executeQuery("select debit from ac_cash_book where shift_no='"+shiftNumber+"'");
while (rset2.next()){
double debit =rset2.getDouble("debit");
if((rset2.getDouble("debit")<=0 ))
status = "no_banked";
else if((rset2.getDouble("debit")==rsetShifts.getDouble("amount"))
&& (rsetShifts.getDouble("amount"))< rsetShifts.getDouble("shift_amount"))
status= "BntClosed";
else if (rset2.getDouble(1)==rsetShifts.getDouble("shift_amount"))
status ="bClosed";
shiftsVector.addElement(rset.getString(1)+":"+rsetShifts.getString(1)+":"+status);
}
}
}
The documentation provides a clear explanation of this:
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. All execution methods in the Statement
interface implicitly close a statment's current ResultSet object if an
open one exists.
So your options would be:
Use a different Statement instance for each query.
Collect all the results from each ResultSet (i.e. into a Set or a List) before moving on to the next one, and then run the comparison on the collected results instead of directly on the result-sets.
Related
If you running a JDBC program from your laptop which is connected to office network over wi-fi.
What happens if network is lost while looping through ( JDBC ) result set?
I noticed java.sql.Connection & Statement objects have timeout. But result set has no time out setting.
ResultSet rs = st.getResultSet();
while (rs.next()) {
int id = rs.getInt(1);
// use this and run some biz logic.
}
I noticed program keep waiting for next results forever. how to make it throw exception ? Has any one experienced this? What did you do ?
ResultSet will not be longer usable, but what you can do is:
You have two options:
First: (and I suggest) using Transactions, As Oracle doc says:
When a connection is created, it is in auto-commit mode. This means
that each individual SQL statement is treated as a transaction and is
automatically committed right after it is executed. (To be more
precise, the default is for a SQL statement to be committed when it is
completed, not when it is executed. A statement is completed when all
of its result sets and update counts have been retrieved. In almost
all cases, however, a statement is completed, and therefore committed,
right after it is executed.)
And in your case you should execute once after all of your statement are completed, in case of network failure or any error in one statement all of your statements will rolled back
Example: reference
public void updateCoffeeSales(HashMap<String, Integer> salesForWeek)
throws SQLException {
PreparedStatement updateSales = null;
PreparedStatement updateTotal = null;
String updateString =
"update " + dbName + ".COFFEES " +
"set SALES = ? where COF_NAME = ?";
String updateStatement =
"update " + dbName + ".COFFEES " +
"set TOTAL = TOTAL + ? " +
"where COF_NAME = ?";
try {
con.setAutoCommit(false);
updateSales = con.prepareStatement(updateString);
updateTotal = con.prepareStatement(updateStatement);
for (Map.Entry<String, Integer> e : salesForWeek.entrySet()) {
updateSales.setInt(1, e.getValue().intValue());
updateSales.setString(2, e.getKey());
updateSales.executeUpdate();
updateTotal.setInt(1, e.getValue().intValue());
updateTotal.setString(2, e.getKey());
updateTotal.executeUpdate();
con.commit();
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
if (con != null) {
try {
System.err.print("Transaction is being rolled back");
con.rollback();
} catch(SQLException excep) {
JDBCTutorialUtilities.printSQLException(excep);
}
}
} finally {
if (updateSales != null) {
updateSales.close();
}
if (updateTotal != null) {
updateTotal.close();
}
con.setAutoCommit(true);
}
}
Second: You may have to buffer all the results before the connection was lost but take care of closing the result set, statement and connection
I want to save two values as one in a database how can I do that?
Here's my code:
try{
String v = "Voila";
String c = "Magic";
String url = "jdbc:mysql://localhost:3306/lemon";
Connection conn = DriverManager.getConnection(url,"r","s");
Statement st = conn.createStatement();
st.executeUpdate("INSERT INTO rtype set RType = '" + v + "'"); // how can I add 'c' in the same column?
conn.close();
}
catch (Exception e) {
System.err.println("Got an exception! ");
JOptionPane.showMessageDialog(null,"Please enter some values");
System.err.println(e.getMessage());
}
As you can see, I have two strings that I should combine as one then save in a database.
The column should have "Voila Magic" if successful.
Just concatenate them at the Java level before the insert:
st.executeUpdate("INSERT INTO rtype set RType = '" + v + " " + c + "'");
// Here ----------------------------------------------^^^^^^^^^^
If either v or c comes from an end user, beware that your code is wide open to SQL injection attacks; here's a humorous, but serious, illustration of them:
Even if they don't, if either could contain ', your statement would end up being invalid SQL and failing. Use PreparedStatement and parameter placeholders instead:
PreparedStatement ps = conn.prepareStatement("INSERT INTO rtype set RType = ?");
ps.setString(1, v + " " + c);
ps.executeUpdate();
try this with modification to your code:
try{
String v = "Voila";
String c = "Magic";
String rType = v + " " + c;
String url = "jdbc:mysql://localhost:3306/lemon";
Connection conn = DriverManager.getConnection(url,"r","s");
Statement st = conn.createStatement();
st.executeUpdate("INSERT INTO rtype set RType = '" + rType + "'"); // how can I add 'c' in the same column?
conn.close();
}
catch (Exception e) {
System.err.println("Got an exception! ");
JOptionPane.showMessageDialog(null,"Please enter some values");
System.err.println(e.getMessage());
}
My suggestion is to use a separator while concatenate the two strings by using any specific character like #, ^ etc., (space likely to occur more common in the strings and avoiding space as a separator by any of the two methods suggested by Crowder.
So that you can split the values you fetch it back from the database in order to show those 2 values in 2 separate fields (probably 2 text fields on a web page) basing on you requirement.
I am trying to update a table using Java JDBC. The method I am using does not throw any errors but the table is not updating. The create table method is below:
public static void Table()
{
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db");
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "CREATE TABLE IF NOT EXISTS CUSTOMERS2 " +
"(PHONE TEXT PRIMARY KEY NOT NULL," +
" SURNAME TEXT NOT NULL, " +
" FIRSTNAME TEXT NOT NULL, " +
" HOME TEXT, " +
" ADDRESS TEXT, " +
" POSTCODE Text)";
stmt.executeUpdate(sql);
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Customers2 created successfully");
}
The update method is below:
public static void updateCustomers()
{
Connection c = null;
PreparedStatement pstmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db");
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query = "UPDATE CUSTOMERS2 set ADDRESS = ? where PHONE = ? ";
pstmt = c.prepareStatement(query); // create a statement
pstmt.setString(1, "1"); // set input parameter 1
pstmt.setString(2, "DOES THIS WORK"); // set input parameter 2
pstmt.executeUpdate(); // execute update statement
pstmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Update Completed successfully HELLO");
}
I have tried to find some clear instructions on this but cant find any. I do not really understand JDBC and prepared statement very well
When autoCommit is false (c.setAutoCommit(false);), you must manually commit the transaction...
Add...
c.commit()
After pstmt.executeUpdate();
You code also has a flaw, in that if some kind of error occurs during the preparation or execution of the statement, both the Connection and PreparedStatement could be left open, causing a resource leak
If you're using Java 7+ you can use the try-with-resources feature, for example...
try {
Class.forName("org.sqlite.JDBC");
try (Connection c = DriverManager.getConnection("jdbc:sqlite:WalkerTechCars.db")) {
c.setAutoCommit(false);
System.out.println("Opened database successfully");
String query = "UPDATE CUSTOMERS2 set ADDRESS = ? where PHONE = ? ";
try (PreparedStatement pstmt = c.prepareStatement(query)) {
pstmt.setString(1, "1"); // set input parameter 1
pstmt.setString(2, "DOES THIS WORK"); // set input parameter 2
pstmt.executeUpdate(); // execute update statement
c.commit();
}
} catch (SQLException exp) {
exp.printStackTrace();
}
} catch (ClassNotFoundException exp) {
exp.printStackTrace();
System.out.println("Failed to load driver");
}
This will ensure that regardless of how you leave the try block the resource will be closed.
You might also consider taking a look at the JDBC(TM) Database Access
Your update method will set ADDRESS to 1 if there is any row in table with PHONE = does this work.
Try to put Address in 1st Input parameter and Phone 2nd Input parameter
When a connection is created, it is in auto-commit mode.
We need to use [setAutoCommit] method only when we need to make Auto Commit false and make it manual commit after executing the query.
More details at Oracle site on JDBC Transaction.
This question already has answers here:
Java ResultSet how to check if there are any results
(23 answers)
Closed 9 years ago.
I've got a problem with my Java plugin - when there's no results found it says that result set is empty. Could someone tell me how to detect if result set is empty?
String url = "jdbc:mysql://" + host + ":" + port + "/" + database + "";
Connection conn = DriverManager.getConnection(url, username, password);
Statement stmt = conn.createStatement();
ResultSet rs;
String p = pp.getName();
rs = stmt.executeQuery("SELECT * FROM " + table + " WHERE username='"
+ p + "' AND recieved=0 ORDER BY id DESC");
rs = stmt.getResultSet();
The standard approach is to attempt to get the next row using the next() method, and check if it returned false (meaning there is no next row, so it's empty). Like this:
ResultSet rs;
// run query on database
if (!rs.next()) {
// no row(s) found from database
} else {
// row(s) found from database OK
}
It can be convenient to code a do...while loop:
if (!rs.next()) {
// handle no rows found
} else {
// process all rows
do {
// process row
} while (rs.next());
}
I have some problems with JDBC's rs.getString("column_name") basically it would not assign the value recieved from the query result, I have a String ris which is supposed to get the row name from rs.getString, for semplicity of the question I'm using ris and my query returns only one row. This is the code:
//It returns null, or any other values I use to initialize the variable
String ris=null;
q = "SELECT DISTINCT nome FROM malattia WHERE eta='" + age + "' AND sesso='" + sexstr + "' AND etnia='" + etniastr + "' AND sintomi IN(" + tes + ")";
ResultSet rs = st.executeQuery(q);
if (!rs.last()) {
ris = "no";
}
else {
//This is the place where I'm having problems
while(rs.next()){
//ris is supposed to get the name of the query result having column "nome"
ris=rs.getString("nome");
}
}
conn.close();
} catch (Exception e) {
ris = e.toString();
}
return ris;
I semplified the code, so it would be easy to focus on where the problem is.
Thanks in advance!
if (rs.last())
while (rs.next())
That won't work, because after you have called last , you are at the last row and next will always return false (it would return true and take you to the next row if there was one left).
And please use a prepared statement with bind variables!
And finally close ResultSet and Connection (or use Jakarta Commons DbUtils).
try this, just remove the rs.last() call in the if condition.. also i agree with #Thilo about using prepared statements.
String ris=null;
q = "SELECT DISTINCT nome FROM malattia WHERE eta='" + age + "' AND sesso='" + sexstr + "' AND etnia='" + etniastr + "' AND sintomi IN(" + tes + ")";
ResultSet rs = st.executeQuery(q);
rs.first(); // go to first record.
//This is the place where I'm having problems
while(rs.next()){
//ris is supposed to get the name of the query result having column "nome"
ris=rs.getString("nome");
}
}
conn.close();