Updating SQL in java - java

i want to update a date in the database under some condition, so i tried this method that i call it in button action performed
public void DeleteDate (JTextField txt1, JTextField txt2)
{
try {
Class.forName("com.mysql.jdbc.Driver");
String m = "IMCDietitian";
String unicode= "?useUnicode=yes&characterEncoding=UTF-8";
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/"+m+""+unicode+"","root","");
System.out.println("connected");
String dept = jComboBox1.getSelectedItem().toString();
Statement st = conn.createStatement();
st.executeUpdate("UPDATE "+dept+" SET edate = '"+jTextField1.getText()+"' WHERE pname = '"+txt1.getText()+"' AND rno = '"+txt2.getText()+"' AND edate = '-'");
}
catch (Exception e) {
e.printStackTrace();
}
}
But it doesn't update any thing in the database. Can any one help me?

There could be these reasons for not seeing any updates:
Perhaps the where clause does not result in any rows being returned therefore no row is updated.
Perhaps autocommit is false. In this case you would need to call commit explicitly. As a note, you could also take a look at transactions.
An Exception but it seems that in this case there is none.
Also, use PreparedStatement - it is cleaner and gets compiled for reuse.

Related

How do I turn my INT (id) into a String in my return from MySQL?

I'm trying to my a very simple webapplication, webshop, for cupcakes.
From the webApp you can choose a cupcake form the dropdown with three attributes
(top, bottom, quantity). These are stored in an ArrayList on my sessionScope but all in numbers e.g. Chokolate as 1 and Vanilla as 2. I want to use these topId numbers to ask my DB (MySQL) for what is in 1 and then have it return Chokolate.
I think I am almost there with my code, but can't get it to return my String, as my topId is an Int.
public static Top getTopById(int topId) {
readFromArrayPutInSQL();
String sql = "INSERT INTO cupcaketopping (toppingType, toppingPrice) VALUES (?, ?)";
try {
ConnectionPool connectionPool = new ConnectionPool();
String query = "SELECT toppingType FROM cupcaketopping";
Statement statement = connectionPool.getConnection().createStatement();
ResultSet rs = statement.executeQuery(query);
rs.getString(topId);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return topId; //Here is the problem - I GUESS?
}
Code after changes due to input in comments, seem to be working!
public static Top getTopById(int topId) {
readFromArrayPutInSQL();
String query = "SELECT toppingType FROM cupcaketopping WHERE toppingID = "+topId+"";
try {
ConnectionPool connectionPool = new ConnectionPool();
PreparedStatement preparedStatement = connectionPool.getConnection().prepareStatement(query);
ResultSet rs = preparedStatement.executeQuery(query);
rs.next();
return new Top(rs.getString(1));
//connectionPool.close(); //NOTE! Won't run, IntelliJ is asking me to delete!
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
There are a few problems:
You're selecting all rows from the cupcaketopping table, regardless of the topId. You should probably be using a PreparedStatement, and then use topId as part of your query.
You never call ResultSet#next(). The result set always starts "before" the first row. You have to call next() for each row in the result set (it returns true if there is a row to read).
The ResultSet#getString(int) method gets the String value of the column at the given index of the result. You only select one column, so the argument should probably be 1 (not topId).
You never close the Statement when done with it.
Depending on how your connection pool class works, you might actually need to close the Connection instead.
You never try to use the String returned by rs.getString(topId).
You never try to convert the query result to a Top instance.
Given it's possible the query will return no result, you might want to consider making the return type Optional<Top>.
The sql string seems to have no purpose.
Your code should look more like this:
public Optional<Top> getTopById(int topId) {
Connection conn = ...;
String query = "SELECT toppingType FROM cupcaketopping WHERE id = ?";
// closes the statement via try-with-resources
try (PreparedStatement stat = conn.prepareStatement(query)) {
stat.setInt(1, topId);
ResultSet rs = stat.executeQuery();
// assume unique result (as it's assumed the ID is the primary key)
if (rs.next()) {
// assumes 'Top' has a constructor that takes a 'String'
return Optional.of(new Top(rs.getString(1)));
} else {
return Optional.empty();
}
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
Your actual implementation may vary, depending on how the rest of your code is designed.

Using Java, what is the best way to update a column in every row with values from an array? (SQLite)

Today is my first day using SQLite. I am using Java to interact with an SQLite database that contains fields called ID, NAME, CITY. I would like to take every record in the database and replace the CITY field with a value from an array. Here is what I tried, but realized right away it was wrong. I believe the query is replacing every record 3 times which gives the result that each CITY field is 'Compton'. I am not sure on what is a good or efficient way to do this.
public void update(String cities[]) throws SQLException {
PreparedStatement updateCity = null;
Connection con = null;
String updateString = "update SUPPLIERS set CITY = ?";
try {
Class.forName("org.sqlite.JDBC");
con = DriverManager.getConnection("jdbc:sqlite:suppliers.db);
con.setAutoCommit(false);
updateCity = con.prepareStatement(updateString);
for (int i = 0; i < cities.length; i++) {
updateCity.setString(1, cities[i]);
updateCity.executeUpdate();
con.commit();
}
} catch (Exception e) {
e.printStackTrace();
if (con != null) {
try {
System.err.print("Transaction is being rolled back");
con.rollback();
} catch (SQLException excep) {
excep.printStackTrace();
}
}
} finally {
if (updateCity != null) {
updateCity.close();
}
con.setAutoCommit(true);
con.close();
}
}
I was calling the method like so instance.update(new String[]{"san diego", "los angeles", "Compton"});. I would like to know how to go about doing this with a PreparedStatement if possible, but if this is not the best way to go, please post an alternative suggestion.
Note: This is not my code, it is code taken from SQLite Java Tutorials.
Your update statement will update ever record in the table each time it is called. If you want the statement to update only one record at a time, you will need to change your update statement to something like this:
update SUPPLIERS set CITY = ? where ID = ?
If you want to update all records, you'll need to execute a query to get all of the IDs. A query like this should work:
select ID from SUPPLIERS
Then for each ID returned, call the update statement using that ID and whatever city you wish to update the record with.

Freezed program after delete record(GUI)

This code:
private void btnDeleteRecordActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
rs.deleteRow();
stmt.close();
rs.close();
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String sql = "SELECT * FROM Workers";
rs = stmt.executeQuery(sql);
rs.next();
int id_col = rs.getInt("ID");
String id = Integer.toString(id_col);
String first = rs.getString("First_Name");
String last = rs.getString("Last_Name");
String job = rs.getString("Job_Title");
textID.setText(id);
textFirstName.setText(first);
textLastName.setText(last);
textJobTitle.setText(job);
} catch (SQLException err) {
// System.out.println(err.getMessage());
JOptionPane.showMessageDialog(Workers.this, err.getMessage());
}
}
AfteI delete one row from database the program freeze. I want to that program will be able to work after a delete button te next and prevrious button will be work.
I used thie: http://www.homeandlearn.co.uk/java/delete_a_record_from_a_database.html
Firstly:
Rather define you Statement and ResultSet within the method you are doing the work, this is better use of scope and safer especially when working with multi-threaded code...
Secondly:
When querying for "Workers", map each row into a POJO and put all POJO's in a collection, then have your app work with the collection instead of the ResultSet.
Thirdly:
When doing an update/delete, create an update/delete statement and use the entries (you are trying to modify's) id (or some other type of unique reference) to the statement.
Looks like your thread is dying from a NullPointerException. First thing you should do would be to find out where the bug is that is causing the NullPointerException and fix it.

Mysql+JDBC+Linux: executeQuery returns empty result set when it shouldn't

I have following code:
public boolean updateDatabase(long houseValue, List<Users> userList)
{
boolean result = false;
Connection conn = null;
PreparedStatement stmtUpdateUsers = null;
PreparedStatement stmtQueryHouse = null;
PreparedStatement stmtUpdateHouse = null;
ResultSet rs = null;
String updateUsers = "UPDATE users SET money = ? WHERE username = ?";
String queryHouse = "SELECT * FROM house WHERE house_id = ?";
String updateHouse = "UPDATE house SET house_money = ? WHERE house_id = ?";
try
{
conn = getConnectionPool().getConnection();
conn.setAutoCommit(false);
stmtUpdateUsers = conn.prepareStatement(updateUsers);
...
// Here is some code that updates Users table in a short loop
...
stmtQueryHouse = conn.prepareStatement(queryHouse);
stmtQueryHouse.setInt(1, 1);
rs = stmtQueryHouse.executeQuery();
if(rs.next())
{
long houseMoney = rs.getLong("house_money");
houseMoney += houseValue;
stmtUpdateHouse = conn.prepareStatement(updateHouse);
stmtUpdateHouse.setLong(1, houseMoney);
stmtUpdateHouse.setInt(2, 1);
stmtUpdateHouse.executeUpdate();
}
else
{
throw new SQLException("Failed to update house: unable to query house table");
}
conn.commit();
result = true;
}
catch(SQLException e)
{
logger.warn(getStackTrace(e));
try{conn.rollback();}catch(SQLException excep)
{
logger.warn(getStackTrace(excep));
}
}
finally
{
DbUtils.closeQuietly(rs);
DbUtils.closeQuietly(stmtQueryHouse);
DbUtils.closeQuietly(stmtUpdateUsers);
DbUtils.closeQuietly(stmtUpdateHouse);
try { conn.setAutoCommit(true); } catch (SQLException e) { /* quiet */ }
DbUtils.closeQuietly(conn);
}
return result
}
This method can be called from multiple threads, house table is just a one row table which holds total earned money. It gets updated by different threads.
Problem is that stmtQueryHouse.executeQuery() returns empty set, and it should not happen, because house table always have (since database creation) one single row that gets updated (only house_money column is updated).
When I run this code on windows (JDBC driver + mysql 5.5.13) it works fine, but when I run it on CentOS (same JDBC driver + mysql 5.1.57) it returns empty result set very often (if not always). Any idea what is going wrong or how could I check where is the problem? Maybe I should use select for update, but then why it works on windows and not on linux? I appreciate any help. Thanks in advance.
Look in the mysql general query log for any errors?
I realize this isnt your question per se, but if you have another table with just a single row for each House, it sounds to me that it would make more sense to move house_money into your main house table
I'd say this one method is doing far too much.
I'd pass in the Connection to three separate methods and manage the transaction outside all of them.
I'd wonder if there's an optimization that would eliminate one of the UPDATES.
I'd want to batch all these so I didn't do a round trip for each and every user. It'll perform poorly as the # of users increases.

delete sql not deleting

I'm trying to delete an event from my table. However I can't seem to get it to work.
My SQL statement is:
public void deleteEvent(String eventName){
String query = "DELETE FROM `Event` WHERE `eventName` ='"+eventName+"' LIMIT 1";
db.update(query);
System.out.println (query);
}
Using MySQL db
Try using the following :
String query = "DELETE FROM `Event` WHERE `eventName` ='"+eventName+"' LIMIT 1";
try {
Connection con = getConnection();
Statement s = con.createStatement();
s.execute(query);
} catch (Exception ex) {
ex.printStackTrace();
}
You have to code your getConnection() method to return a valid Database Connection.
I would suggest using Statement.executeUpdate method, since it returns an integer. So after performing this delete query you will also have information if you really deleted any records (in this case you would expect this method to return 1, since you are using LIMIT=1). I would also suggest closing Statement as soon as you don't need it, here is skeleton implementation:
private void performDelete(Connection conn, String deleteQuery, int expectedResult) throws SQLException {
Statement stmt = conn.createStatement();
int result = -1;
try {
result = stmt.executeUpdate(deleteQuery);
if(result != expectedResult) {
//Here you can check the result. Perhaps you don't need this part
throw new IllegalStateException("Develete query did not return expected value");
}
} catch(SQLException e) {
//Good practice if you use loggers - log it here and rethrow upper.
//Or perhaps you don't need to bother in upper layer if the operation
//was successful or not - in such case, just log it and thats it.
throw e;
} finally {
//This should be always used in conjunction with ReultSets.
//It is not 100% necessary here, but it will not hurt
stmt.close();
}
}

Categories