Delete from database using Prepared Statement - java

I'm want to delete a person from the database "person" on a given id. It works if I don't use Prepared Statement (the first 5 unmarked lines of code in the try-statement).
But when I try to do it using Prepared Statement it does not work, and I canĀ“t figure out why?
The application gets stuck on prepStatement.executeUpdate();
Therefore I can't even see the value of executeUpdate (if I want to se how many Changes that are made).
I have a similar method, addPerson, where Prepered Statement works perfect. This really confuses me...
I appreciate your help.
private void removePerson() {
int id = Integer.parseInt(idField.getText());
PreparedStatement prepStatement = null;
try {
*/* Statement statement = connection.createStatement();
String sql = "DELETE FROM person WHERE id = '"+id+"'";
statement.executeUpdate(sql);
System.out.println("Person removed from database...");
ResultSet result = statement.executeQuery(sql);
*/*
String sql = "DELETE FROM person WHREE id = ?";
prepStatement = connection.prepareStatement(sql);
prepStatement.setInt(1, id);
prepStatement.executeUpdate();
System.out.println("Person removed from database...");
}
catch (SQLException se) {
se.toString();
}
finally {
try {
prepStatement.close();
}
catch (SQLException ex) {
ex.toString();
}
}
}

Related

Unable to execute prepared Statement from DAO

So currently Im trying to do get the auto-incremented primary key by following this answer
Primary key from inserted row jdbc? but apparently the program can't even reach that line and the error appeared on the ps.executeQuery() line after debugging the program, the error it display was only "executeQuery" is not a known variable in the current context. that line, which didn't make sense to me. So how do I go pass this hurdle?
public static int createNewLoginUsers(String newPassword, String newRole) throws SQLException{
Connection conn = DBConnection.getConnection();
Statement st = null;
ResultSet rs = null;
PreparedStatement ps = null;
int id = 0;
try{
String sql = "INSERT into Login(password, role) VALUES(?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, newPassword);
ps.setString(2, newRole);
ps.executeUpdate();
st = conn.createStatement();
rs = st.executeQuery("SELECT * from Login");
rs.last();
System.out.println(rs.getInt("username"));
id = rs.getInt("username");
rs.close();
} finally{
try{
conn.close();
}catch(SQLException e){
System.out.println(e);
}
}
return id;
}
The part of the method which calls the createNewLoginUsers method
if(newPasstxtfld.getText().equals(retypeNewPasstxtfld.getText())){
//update into database
try {
int username = CreateUsersDAO.createNewLoginUsers( (String) newUserRoleBox.getSelectionModel().getSelectedItem(), newPasstxtfld.getText());
Alert confirmation = new Alert(Alert.AlertType.INFORMATION);
confirmation.setHeaderText("New User Details has been created. Your username is " + username);
confirmation.showAndWait();
} catch (SQLException e) {
}
EDIT:
Databases table added and it's in the provided link below
https://imgur.com/a/Dggp2kc and edit to the codes instead of 2 try blocks in one method i have placed it into a different similar method, updated my codes to the current one I have.

PreparedStatement to update one value based on another in a record

I have below table structure
id msg keyword
-----------------
1 abc ?
2 xyz ?
The above is just an example; however my real table looks like that only. Based on the value of msg field, I need to call an API that would calculate the keywords from the msg and then update the particular record. How can I get the record and update as well, at the same time using Java PreparedStatement?
Also since my database is very large, what would be the efficient way to do it? Below is the code snippet :
public void updateColumns() {
try {
PreparedStatement stmt = null;
ResultSet resultSet = null;
String query = "select * from '" + Constants.tableName + "'";
// How to uypdate the record here by calling my custom API that reads the msg and returns the keywords in the message??
stmt = conn.prepareStatement(query);
stmt.execute();
stmt.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The idiomatic JDBC solution would be to generate a batch update :
String select = "SELECT id, msg FROM my_table";
String update = "UPDATE my_table SET keyword = ? WHERE id = ?";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(select);
PreparedStatement ps = conn.prepareStatement(update);) {
while (rs.next()) {
ps.setInt(1, rs.getInt(1));
ps.setString(2, MyAPI.calculateKeyword(rs.getString(2));
ps.addBatch();
}
ps.executeBatch();
}
Of course, if you table is very large, you may which to consider every X rows.

Rollback does not work

I want to rollback all records have been inserted to table when exception occurs.
but conInsert.rollback() doesn't work.
Maybe I miss some code?
Here is my code
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(connectionUrl);
//con.setAutoCommit(false);
Statement st = con.createStatement();
String querySelectOrderInTp = "SELECT order_in_tp_id, order_in_tp_qty, order_in_tp_price, order_in_tp_article_tc_id, order_in_tp_warehouse_tc_id, inv_stock_tp_id, inv_stock_tp_qty_available from order_in_tp LEFT JOIN inv_stock_tp on(order_in_tp_warehouse_tc_id=inv_stock_tp_whouse_current_id AND order_in_tp_article_tc_id=inv_stock_tp_article_tc_id AND order_in_tp_price=inv_stock_tp_price) where order_in_tp_pick_up_timestamp = 'A' AND order_in_tp_date = '2013-06-11' GROUP BY order_in_tp_id;";
ResultSet rs = st.executeQuery(querySelectOrderInTp);
String queryUpdateInvStockTp = "INSERT INTO inv_stock_tp (cre_tms,upd_tms,cre_usr,upd_usr,version,usr_act,inv_stock_tp_id,inv_stock_tp_key, inv_stock_tp_whouse_current_id,inv_stock_tp_article_tc_id,inv_stock_tp_qty_available,inv_stock_tp_qty_min,inv_stock_tp_price) VALUES (NOW(),NOW(),'demo2','demo2',1,'A',null,'AAAA',?,?,?,0,2000.0000)";
conInsert = DriverManager.getConnection(connectionUrl);
conInsert.setAutoCommit(false);
ps = conInsert.prepareStatement(queryUpdateInvStockTp);
String queryUpdateOrderInTp = "UPDATE order_in_tp set order_in_tp_pick_up_timestamp = ? WHERE order_in_tp_id = ?";
psUpdate = con.prepareStatement(queryUpdateOrderInTp);
while(rs.next()) {
Integer qty = rs.getInt(7) - rs.getInt(2);
ps.setString(1, rs.getString(5));
ps.setString(2, rs.getString(4));
ps.setString(3, rs.getString(2));
ps.execute();
psUpdate.setString(1, "A");
psUpdate.setString(2, rs.getString(1));
psUpdate.execute();
ps.clearParameters();
psUpdate.clearParameters();
}
conInsert.commit();
} catch (Exception e) {
e.printStackTrace();
if (conInsert != null) {
try {
System.err.print("Transaction is being rolled back");
conInsert.rollback();
} catch (SQLException excep) {
excep.printStackTrace();
}
}
}
I make an exception in last record but all record before it still have been inserted.
By default, MySQL runs with autocommit mode enabled. This means that as soon as you execute a statement that updates (modifies) a table, MySQL stores the update on disk to make it permanent. I dont know java, but make sure that You have the START TRANSACTION statement, and then COMMIT or ROLLBACK.

Delete row from database

I have a database table with the following layout:
Columns:
_________________________
id | user_name | password
But I can't delete a specified row by using the username.
I am receiving the following error:
MySQLSyntaxErrorException: Unknown column 'vipin' in 'where clause'
vipin is a value within the table.
Can anyone help me?
public void deleteFclty() {
PreparedStatement stmt = null;
ResultSet rs = null;
String username = removeText.getText();
ArrayList<String> values = new ArrayList();
String qry = "SELECT user_name From users ";
try {
stmt = (PreparedStatement) connection.prepareStatement(qry);
rs = stmt.executeQuery();
while (rs.next()) {
values.add(0, rs.getString(("user_name")));
System.out.println(values);
}
} catch (SQLException ex) {
Logger.getLogger(RemoveFaculty.class.getName()).log(Level.SEVERE, null, ex);
}
if (values.contains(username)) {
username = removeText.getText();
Boolean isAdmin = false;
try {
System.out.println(username);
preparedStatement = (PreparedStatement) connection.prepareStatement("DELETE FROM users WHERE user_name=" + username + "");
preparedStatement.executeUpdate();
} catch (SQLException ex) {
Logger.getLogger(RemoveFaculty.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
Util.showErrorMessageDialog(username + " is not found.Please try again.");
}
}
Since you're already using PreparedStatement, use it right and pass the username as parameter instead of just concatenating the Strings:
//no need to use a cast here
preparedStatement = connection.prepareStatement(
//note the usage of ? instead of concatenating Strings
"DELETE FROM users WHERE user_name=?");
//setting the first parameter in the query string to be username
preparedStatement.setString(1, username);
preparedStatement.executeUpdate();
Using this, you won't have any concatenation problems and what's better, your code won't be prone to SQL Injection.
Not directly related to your problem, but it would be better if you move the code to execute INSERT, UPDATE and DELETE statements to a single method.
public void executeUpdate(Connection con, String query, Object ... params)
throws SQLException {
PreparedStatement pstmt = con.prepareStatement(query);
if (params != null) {
int i = 1;
for(Object param : params) {
pstmt.setObject(i++, param);
}
}
pstmt.executeUpdate();
pstmt.close();
}
So your code would be dramatically reduced to:
String deleteSQL = "DELETE FROM users WHERE user_name=?";
executeUpdate(deleteSQL, username);
Note that you can create a new method based on this approach to execute SELECT statements.
Also, don't forget to close your resources. This also can be dramatically reduced using a method like this:
public void closeResource(AutoCloseable res) {
try {
if (res != null) {
res.close();
}
} catch (Exception e) {
//handle this exception...
//basic example, not meant to be used in production!
e.printStacktrace(System.out);
}
}
Note that Connection, Statement (and its children PreparedStatement and CallableStatement) and ResultSet interfaces already extend from AutoCloseable.
You haven't quoted the username you're inserting into the query, so it's being treated as a reference to a field name:
DELETE FROM users WHERE user_name='"+username+"'"
^-- ^--
Note: building queries like this leaves you open to SQL injection attacks. Used prepared statements and placeholders instead.
I think you might need some quotes round the username in the where clause
connection.prepareStatement("DELETE FROM users WHERE user_name='"+username+"'");
You are going to want to quote your Strings
"DELETE FROM users WHERE user_name="+username+"";
Like this:
"DELETE FROM users WHERE user_name='" + username + "'";
What would be better is just using PreparedStatement as it was intended:
"DELETE FROM users WHERE user_name = ?";
And then using:
preparedStatement.setString(1, username);
before calling executeUpdate
The query should look like this
preparedStatement = (PreparedStatement) connection.prepareStatement("DELETE FROM users WHERE user_name='"+username+"'");
Note : Mind the single quotes used for user_name='"+username+"'"

Result set usage when expected one int value only

I know it is basics and probably really simple, but I'm struggling with the following situation where i want to query the database for a specific int(id in my case), but somehow i can't acces the returned data from the data set.
I have tested the query in db managment system and it works. I get no errors/ stacks but the result of my method is always -1.(Which means it fails :( because no int has been parsed)
code:
public int UserFactoryEngine(String n, String p){
// query for user data, validate and return
Connection conn = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
System.out.println("Failure intialization of the driver! ");
e.printStackTrace();
}
String connectionUrl = "jdbc:sqlserver://localhost:1433;" + "databaseName=BugsSurveillance;user=sa;password=1234;integratedSecurity=true;";
try {
conn = DriverManager.getConnection(connectionUrl);
} catch (SQLException e) {
System.out.println("Failure intialization of the connection! ");
e.printStackTrace();
}
System.out.println("Connected... ");
String sqlquery;
PreparedStatement preparedStatement;
ResultSet rs;
try {
preparedStatement = conn.prepareStatement("SELECT id FROM Users WHERE name = ? AND pass = ? ",
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
preparedStatement.setString(1, n);
preparedStatement.setString(2, p);
rs = preparedStatement.executeQuery();
while (rs.next()){
System.out.println(rs.getInt(1));
}
} catch (SQLException e) {
System.out.println("Prepared statement failure!");
e.printStackTrace();
}
return -1;
}
You're not getting any output to the console from the
while (rs.next()){
System.out.println(rs.getInt(1));
}
because there are no results. Initially the ResultSet is pointed before the first row. When next() is called, it increments to the next row, and returns true only if the new current row is valid, which it must not be in this case.
Since you say the row exists, try replacing your lines
preparedStatement.setString(1, n);
preparedStatement.setString(2, p);
with hard coded values, for testing. So, if your username is admin, and your password is 1234.
preparedStatement.setString(1, "admin");
preparedStatement.setString(2, "1234");
Another test you could try is to
SELECT * FROM users
and see if you get any results that way.
Considering this is a login factory(what i'm trying to implement) i have been using a JPasswordField, which it seems needs a bit more atention when it comes to the getPassword() method. So because of that I wasen't able to succesfully find some matching string in database.
Fix: used JTextfield with hidden characters.

Categories