I am not able to execute an update statement. There seems to be some issue with my update statement.
What I'm doing now is that I'm trying to update the duplicated email address and replace (update) with non-duplicated email. Therefore, in order to update, my SQL statement will check my database against the input and if ((firstname && lastname && dateofbirth) || (phoneNo && address) match what the user input, it will update the database; that is: update the duplicated email address with non-duplicated email, then remove all the duplicated email after the update has been executed.
However, I'm not able to figure out what's wrong. Here is my update statement:
try {
System.out.println("it came here where filepart!=null");
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(dbURL, dbUser, dbPass);
// connects to the database
conn = getConnection();
// constructs SQL statement
stmt = conn.createStatement();
//sqll should be update
String sql1 ="UPDATE registration SET emailAddress = ? where ((firstName = ? && lastName= ? && dateOfBirth= ?) || (phoneNo= ? && address= ?))" ;
//Using a PreparedStatement to save the file
PreparedStatement statement1 = conn.prepareStatement(sql1);
System.out.println(firstName+"firstname");
statement1.setString(1, firstName);
statement1.setString(2, lastName);
statement1.setString(3, dateOfBirth);
statement1.setString(4, phoneNo);
statement1.setString(5, address);
statement1.executeUpdate();
statement1.close();
String sql2="delete registration from registration inner join (select min(userId) as lastId, emailAddress from registration where emailAddress in ( select emailAddress from registration group by emailAddress having count(*) > 1) group by emailAddress) duplic on duplic.emailAddress = registration.emailAddress where registration.userId > duplic.lastId";
stmt.executeUpdate(sql2);
//sends the statement to the database server
// if (row > 0) {
// getServletContext().getRequestDispatcher("/Message.jsp").include(request, response);
// message = "You have successfully registered.";
//}
} catch (SQLException ex) {
// message = "You have failed to registered. Please try again.";
// ex.printStackTrace();
} finally {
if (conn != null) {
// closes the database connection
try {
conn.close();
} catch (SQLException ex) {
// ex.printStackTrace();
//silent
//message="You have failed to log in";
getServletContext().getRequestDispatcher("/FailedMsg.jsp").include(request, response);
}
}
rs.close();
ps.close();
conn.close();
}}
}
Look at your sql string first:
String sql1 ="UPDATE registration SET emailAddress = ? where ((firstName = ? && lastName= ? && dateOfBirth= ?) || (phoneNo= ? && address= ?))" ;
In the above string you have 6 question marks (placeholders). But you are setting only the five of them and indeed in the wrong way. What you are doing is set firstname for emailAddress, lastname for firstName and so on. The first placeholder(?) is for emailAddress so you have to do as follows:
statement1.setString(1, emailAddress);
statement1.setString(2, firstName);
statement1.setString(3, lastName);
statement1.setString(4, dateOfBirth);
statement1.setString(5, phoneNo);
statement1.setString(6, address);
Can this be a reason you cannot update correctly? You might also be getting some exception. You should look to the RAD console.
The issue might be at where clause. Try to apply Trim() , ToUpper(), or ToLower() function to string data columns and input value. Try to match firstname, lastname, and dateofbirth first. If it works, try with matching phone and address data. Don't forget to clean up/normalize data before you match.
Related
I have this java method:
public boolean insertAuthor(String userid, String password){
try{
String query1 = "INSERT INTO user (id, firstName, lastName, belonging, country) VALUES(?,?,?,?,?)";
PreparedStatement stmt = this.dbConn.prepareStatement(query1);
stmt.setInt(1,0);
stmt.setString(2,"default"); //Yes, it's correct with "default"
stmt.setString(3,"default");
stmt.setString(4,"default");
stmt.setString(5,"default");
//stmt.executeUpdate();
stmt.executeUpdate(query1, PreparedStatement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
int key=0;
if ( rs.next() ) {
key = rs.getInt(1);
}
String query2 = "INSERT INTO authentication (id, address, password, user_id, login_id) VALUES(?,?,?,?,?)";
stmt = this.dbConn.prepareStatement(query2);
stmt.setInt(1,0);
stmt.setString(2,"default");
stmt.setString(2,password);
stmt.setInt(2,key);
stmt.setString(2,userid);
stmt.executeUpdate();
return true;
}catch(Exception e){
System.err.println(e.getMessage());
}
return false;
}
Let me explain: I would like to execute two queries and the second one need the key that is generated in the first query (I need the primary key of the table "user" because user-authentication is a 1:1 relationship).
So:
Is this the correct way to execute more than one query?
Am I missing something with the returning key? Because if I run ONLY executeUpdate() and I comment every row below it the method works fine, but when I run the code in the example (with the first executeUpdate() commented) I get false (only false, no exception). Do I have to check something in my database?
Thanks in advance.
EDIT:
I found a solution. It was an error in columns and not in the method for getting the generated key itself. I will choose Joop Eggen's answer for the improvements that he showed me. Thanks!
There were a couple of improvements needed.
String query1 = "INSERT INTO user (firstName, lastName, belonging, country)"
+ " VALUES(?,?,?,?)";
String query2 = "INSERT INTO authentication (address, password, user_id, login_id)"
+ " VALUES(?,?,?,?)";
try (PreparedStatement stmt1 = this.dbConn.prepareStatement(query1,
PreparedStatement.RETURN_GENERATED_KEYS);
stmt2 = this.dbConn.prepareStatement(query2)) {
stmt1.setString(1, "default");
stmt1.setString(2, "default");
stmt1.setString(3, "default");
stmt1.setString(4, "default");
stmt1.executeUpdate();
try (ResultSet rs = stmt1.getGeneratedKeys()) {
if (rs.next()) {
int userid = rs.getInt(1);
stmt2.setString(1, "default");
stmt2.setString(2, password);
stmt2.setInt(3, key);
stmt2.setString(4, userid);
stmt2.executeUpdate();
return true;
}
}
} catch (SQLException e) {
System.err.println(e.getMessage());
}
return false;
Try-with-resources close automatically, also on exception and return.
You have two prepared statements to close.
The executeUpdate with the SQL is for the parents class Statement, and does disrespect the parameter settings. You chose that for the generated keys parameter, but that goes into Connection.prepareStatement.
(SQL) The generated keys should not be listed/quasi-inserted.
It is debatable whether one should catch the SQLException here. throws SQLException is what works for me.
I'll advise you have a username field in your user table so after inserting you can simply do a Select id from user Where username...
may i know whats wrong with my insert sql statement at java as the sql statement allows me to insert everything into database, leaving my profilepic empty. Currently, what im trying to do is that, i am trying to duplicate the image from userId=143 into the new user. However, the duplication of image doesn't work at java.
On the other hand, at mysql database registration table, there is data for userId=143 and with image. I tried to execute the following sql statement and it works prefectly as what i wanted.
insert into registration
(profilepic, firstName,lastName,phoneNo,dateOfBirth,displayname,password,
emailAddress, address, interest )
select (select profilepic from registration where userId =
143),'ab','cd',94329,'2016-11-11','af','de','gf','ge','ee' ;
However, it doesn't work if i use the exact format for sql statement at java. I'm not able to figure out what's wrong with my sql statement. Your help will be much appreciated. Thanks.
try{
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
conn = DriverManager.getConnection(dbURL, dbUser, dbPass);
// connects to the database
conn = getConnection();
// constructs SQL statement
stmt = conn.createStatement();
String sql1 =" insert into registration (profilepic, firstName, lastName,phoneNo,dateOfBirth,displayname,password,emailAddress, address, interest ) select (select profilepic from registration where userId = 143),?,?,?,?,?,?,?,?,? ";
//Using a PreparedStatement to save the file
PreparedStatement statement1 = conn.prepareStatement(sql1);
statement1.setString(1, firstName);
statement1.setString(2, lastName);
statement1.setString(3, phoneNo);
statement1.setString(4, dateOfBirth);
statement1.setString(5, displayName);
statement1.setString(6, password);
statement1.setString(7,emailAddress);
statement1.setString(8, address);
statement1.setString(9, interest);
//sends the statement to the database server
int row = statement1.executeUpdate();
if (row > 0) {
getServletContext().getRequestDispatcher("/Message.jsp").include(request, response);
// message = "You have successfully registered.";
}
} catch (SQLException ex) {
// message = "You have failed to registered. Please try again.";
// ex.printStackTrace();
} finally {
if (conn != null) {
// closes the database connection
try {
conn.close();
} catch (SQLException ex) {
// ex.printStackTrace();
//silent
//message="You have failed to log in";
getServletContext().getRequestDispatcher("/FailedMsg.jsp").include(request, response);
}
}
}
Try modifying your query like below having only a single SELECT statement and avoiding the inner sub-select.
insert into registration
(profilepic, firstName,lastName,phoneNo,dateOfBirth,displayname,password,
emailAddress, address, interest )
select profilepic,'ab','cd',94329,
'2016-11-11','af','de','gf','ge','ee'
from registration
where userId = 143;
public int addUsers(int USER_ID,String FIRST_NAME,String LAST_NAME,String PASSWORD,String USERNAME,String USER_PERMISSION) throws SQLException {
Connection conn = null;
conn = getConnectivity(conn) ;
getConnectivity(conn);
String sqlSelect = "SELECT * from USER_DETAILS";
PreparedStatement pres = conn.prepareStatement(sqlSelect);
ResultSet rs1 = pres.executeQuery();
if(rs1.next()){
String Username = rs1.getString(5);
System.out.println("username found "+Username);
System.out.println("username input " + USERNAME);
System.out.println("password input " + PASSWORD);
if (Username.equals(USERNAME)){
System.out.println("Username already exists");
conn.close();
}
else{
System.out.println("FOUND ELSE");
String sql = "INSERT INTO USER_DETAILS VALUES (?,?,?,?,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, USER_ID);
ps.setString(2, FIRST_NAME);
ps.setString(3,LAST_NAME);
ps.setString(4,PASSWORD);
ps.setString(5,USERNAME);
ps.setString(6,USER_PERMISSION);
int result = ps.executeUpdate();
System.out.println(result);
}
}
conn.close();
return USER_ID;
}
and for login I am using
public boolean login(String USERNAME, String PASSWORD) throws SQLException
{
boolean result = false;
Connection conn = null;
conn = getConnectivity(conn) ;
String sqlSelect = "SELECT * from USER_DETAILS";
PreparedStatement pres = conn.prepareStatement(sqlSelect);
ResultSet rs1 = pres.executeQuery();
if(rs1.next()){
String Username = rs1.getString(5);
String Password = rs1.getString(4);
String UserPermission = rs1.getString(6);
System.out.println("username found "+Username);
System.out.println("username input " + USERNAME);
System.out.println("password input " + PASSWORD);
if (Username.equalsIgnoreCase(USERNAME) && Password.equalsIgnoreCase(PASSWORD) && UserPermission.equalsIgnoreCase("blocked")){
System.out.println("User Logged in");
conn.close();
}
System.out.println("gets out of the code");
}
conn.close();
return result;
}
first of all it is allowing to enter more than one entry, so duplicates occurring regardless of my if statement, and when i add fresh new data and try to see I can log in, it still compares with previously added data and does not work. Can someone see what am i doing wrong here. please thanks
below is the system print out i get ,
Connection Valid
username found kamran (don't know why he is still picking up this column)
username input macbook (these i have already in my database)
password input hello (these i have already in my database)
gets out of the code
Connection Valid
Connection Valid
username found kamran (don't know why he is still picking up this column)
username input macho (these i have already in my database)
password input hello (these i have already in my database)
FOUND ELSE (dont know why it adds data when they already exist in database)
1
Your code doesn't make sense: you are querying for all users and only checking the first returned user if it matches. Of course that is going to fail if the first returned user doesn't match: in addUsers you will try to add the user if the first user returned doesn't match, in login a user can only login if it is the first user.
You need to use a WHERE clause to only request the user you want to check:
// Note: this assumes a case insensitive collation
String sqlSelect = "SELECT * from USER_DETAILS WHERE username = ?";
try (PreparedStatement pres = conn.prepareStatement(sqlSelect)) {
pres.setString(1, USERNAME);
try (ResultSet rs1 = pres.executeQuery()) {
if (!rs1.next) {
// user doesn't exist yet, create...
}
}
}
You need to do something similar for login (but then with if (rs1.next()) instead).
There are more problems with your current code: you are storing plaintext passwords: you should really hash them with a strong password hash like PBKDF2. Also please follow the java naming conventions. Variables and parameters are camelcase so not USERNAME but username (or userName), not UserPermission, but userPermission. This improves the readability for people who are used to the java naming conventions.
I'm having a hard time understanding why this wont work, if I type the exact same thing straight into a MySQL console it accepts it but when ever I try to run it, it reports a syntax error.
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= '6'' at line 1
All I'm trying to do is receive the data in the row with the member_id value of whatever the user inputs. For testing purposes the value is always 6, I have tried parsing it as int instead of a string, which gave the same error, and I tried just adding the ID variable onto the end of the string instead of using a place holder but it didn't like that much either.
Here is the code:
public class MemberDAO {
public PreparedStatement ps = null;
public Connection dbConnection = null;
public List<Member> getMembersDetails(String ID) throws SQLException{
List<Member> membersDetails = new ArrayList();
String getMembershipDetails = "SELECT first_name, last_name, phone_number, email, over_18, date_joined, date_expire, fines FROM members"
+ "WHERE member_id = ?";
try {
DBConnection mc = new DBConnection();
dbConnection = mc.getConnection();
ps = dbConnection.prepareStatement(getMembershipDetails);
ps.setString(1, ID);
ps.executeQuery();
ResultSet rs = ps.executeQuery(getMembershipDetails);
String firstName = rs.getString("first_name");
String lastName = rs.getString("last_name");
String phoneNumber = rs.getString("phone_number");
String email = rs.getString("email");
String over18 = rs.getString("over_18");
String dateJoined = rs.getString("date_joined");
String dateExpired = rs.getString("date_expire");
String fines = rs.getString("fines");
Member m;
m = new Member(firstName, lastName, phoneNumber, email, over18, dateJoined, dateExpired, fines);
membersDetails.add(m);
} catch (SQLException ex){
System.err.println(ex);
System.out.println("Failed to get Membership Details.");
return null;
} finally{
if (ps != null){
ps.close();
}
if (dbConnection != null){
dbConnection.close();
}
} return membersDetails;
}
This is what's calling it:
private void btnChangeCustomerActionPerformed(java.awt.event.ActionEvent evt) {
customerID = JOptionPane.showInputDialog(null, "Enter Customer ID.");
MemberDAO member = new MemberDAO();
try {
List membersDetails = member.getMembersDetails(customerID);
txtFullName.setText(membersDetails.get(0) + " " + membersDetails.get(1));
} catch (SQLException ex) {
System.err.println(ex);
System.out.println("Failed to get Details.");
JOptionPane.showMessageDialog(null, "Failed to retrieve data.");
}
}
Any input is appreciated.
Your query is missing a space:
...fines FROM members"
+ "WHERE...
Will result in
FROM membersWHERE
Which is invalid SQL
Change it to
+ " WHERE....
your query is:
SELECT first_name, last_name, phone_number, email, over_18, date_joined, date_expire, fines FROM
members WHERE member_id = ?
So between member and where you need a blank character
SELECT first_name, last_name, phone_number, email, over_18, date_joined, date_expire, fines FROM members WHERE member_id = ?
I am working on a project to create a login page. To do this I am using a database to store the user information. As of right now there are four columns in my database: username, password, email, and admin.
Right now I am having a problem accessing that database using a prepared statement/Result set format. Right now I get to the third return, print out the imputed username and password then generate an error. Am I formatting my prepared statement incorrectly?
Okay, based of previous answers I have corrected most of my code(thank you) and now I have this error when I am trying to print out of the result set:
java.sql.SQLException: Column Index out of range, 2 > 1.
any ideas?
My code:
Properties props = new Properties();
props.setProperty("user", "root");
props.setProperty("password", "root");
props.setProperty("databaseName", "dbname");
String ret = ERROR;
Connection myCon = null;
try{
System.out.println("got here 1!");
Class.forName ("com.mysql.jdbc.Driver").newInstance();
System.out.println("got here 2!");
myCon = DriverManager.getConnection("jdbc:mysql://ipaddresshere:3306/dbname",props);
System.out.println("got here 3!");
System.out.println(username);
System.out.println(password);
String dbQuery = "SELECT count(*) FROM loginTestTable where username = "+username+" AND password = "+password+"";
//PreparedStatement prep = myCon.prepareStatement(dbQuery);"
PreparedStatement ps = myCon.prepareStatement(dbQuery);
ps.setString(1, username);
ps.setString(2, password);
ResultSet result = ps.executeQuery();
System.out.println("got here 4!");
while (result.next()) {
System.out.println("got here 5!");
ret = SUCCESS;
System.out.println("username: "+result.getString(1)+" password: "+result.getString(2)+" email: "+result.getString(3));
if(result.getString(4).toLowerCase()=="YES"){
ret = "admin";
}
}
}catch(Exception e){
System.out.println("arg there be an error me matey!");
ret = ERROR;
}finally{
if(myCon!=null){
try{
myCon.close();
}catch (Exception e){
}
}
}
return ret;
There are multiple problems with your code:
First, you're missing quotes around username and password.
String dbQuery = "SELECT count(*) FROM loginTestTable " +
"where username = '"+username+"' AND password = '"+password+"'";
Second, the PreparedStatement#setString() methods have no effect unless you define your query with place holders ? like
String dbQuery = "SELECT count(*) FROM loginTestTable " +
"where username = ? AND password = ?";
Third, you must never compare strings with equality == operator. Use String.equals() as
// also note you need toUpperCase() here
"YES".equals(result.getString(4).toUpperCase());
Change the line:
String dbQuery = "SELECT count(*) FROM loginTestTable where username = "+username+" AND password = "+password+"";
By:
String dbQuery = "SELECT count(*) FROM loginTestTable where username = ? AND password = ?";