How can I avoid entering duplicate entries in my MySQL database? - java

So, what I'm trying to do here is check the user table in my users mySQL database for duplicate entries in the username row, before inserting a new username. Here's an example of my code. Currently, the results ResultSet does not do anything and I'm not exactly sure how to implement it into the IF statement that follows. And yes, I have the catches for the try, just not in this example. Sorry if this is a rather simple question, I just started programming with Java last week. Also, it's my first question on here and I definitely appreciate the help.
try{
String sequel = ("SELECT username FROM `users`.`user`");
PreparedStatement userNameInfo = conn.prepareStatement(sequel);
userNameInfo.executeQuery(sequel);
ResultSet results = userNameInfo.getResultSet();
if (sequel.equals("")) {
conn.setAutoCommit(false);
String sql = "INSERT INTO `users`.`user`(`username`,`password`,`email`) VALUES('" + newusername +"', '" + newpassword + "', '" + newemail +"')";
PreparedStatement prest = conn.prepareStatement(sql);
prest.executeUpdate(sql);
conn.commit();
conn.close();
System.out.println("Added Successfully!");
}
else {
System.out.println("Add failed!");
}
}

So I think what you trying to do - and should do I think, is select if the username is in the table then add or not. So the sql needs to be like:
select username from users where username = ?
then set the param in the query. See docs here:
http://docs.oracle.com/javase/6/docs/api/java/sql/PreparedStatement.html
You then need to check what is in the resultset after the query, and see if anything is in there. The API docs for this will be in about the same place as the PreparedStatement docs.
Adding a constraint in the db will also give you a belt and braces.
Hope this helps

When you define your SQL table, you can define some items to be unique.
So in your example, if you want usernames to be unique, you would add:
UNIQUE(username)
to your table declaration.
If you want the pair username / email to be unique, you would add:
UNIQUE(username, email)
The documentation is here

Have you created the primary key in the table? A primary key automatically prevents duplicate values.
If you want to prevent duplicate usernames, then make your username column the primary key.

Umm, I am not a java guy. But this may help you.
You can retrieve the row count of the first result set after the query executes. If the row count is equal to 0, that means database does not contain a similar record.

Related

Can't delete record from MySQL database

Trying to delete record from my database, but I get the error "Unknown column '' in 'where clause'".
private void deleteUser() {
String query = "DELETE FROM user WHERE Name =" + tfemail.getText() + "";
executeQuery(query);
showUsers();
}
You can't write queries this way. Imagine someone put in the tfemail field this text:
"Joe' OR FALSE"
and let's see what that would do to your SQL query:
DELETE FROM user WHERE Name = 'Joe' OR FALSE;
bye, database!
Some dbs let you execute stuff on the server the db engine runs on. Which means this trick can be used to completely hack the machine or format the disk entirely. bye, entire machine.
This also means your executeQuery method needs to be removed - that abstraction ('here is some SQL, please run it') is rarely useful (as it cannot contain any user input), and entices you to write security leaks.
The solution is prepared statements:
PreparedStatement ps = con.prepareStatement("DELETE FROM user WHERE Name = ?");
ps.setString(1, "Joe");
ps.executeUpdate();
This solves your problem, and does so safely - ps.setString(1, "Joe' OR FALSE"); is now no longer an issue (the DB engine or JDBC driver guarantees that it will take care of the problem; the effect would be to delete the entry in your user table that literally reads "Joe' OR FALSE").
Furthermore, storing passwords in a database is not an acceptable strategy; the solution is e.g. bcrypt: Use a hashing algorithm designed specifically to store passwords.
String query = "DELETE FROM user WHERE Name ='" + tfemail.getText() + "'";
^ ^
|___________add___________|

Can I pass column names in this manner?

query = "UPDATE personal_details SET '" + field + "' = '" + edit + "' WHERE associate_id = '" + associate_id + "'";
Here my table name is personal_details and I am taking the table column name as a parameter in the variable filed and its new value in edit. This code is in Java. and the database I'm accessing is in PostgreSQL.
Although you can build string using plain concatenation, the more recommended ways are:
Use StringBuilder/StringBuffer when you build strings to optimize program speed, specially if you concatenate strings inside loop;
The most recommended way is to use PreparedStatement and fill parameter values. See: http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
Don't construct queries like this! It is bad practice due to security issues, as #Rory pointed out. Instead use a PreparedStatement with parameters, for example:
String updateTableSQL = "UPDATE DBUSER SET USERNAME = ? WHERE USER_ID = ?";
PreparedStatement preparedStatement = dbConnection.prepareStatement(updateTableSQL);
preparedStatement.setString(1, "mkyong_new_value");
preparedStatement.setInt(2, 1001);
// execute insert SQL stetement
preparedStatement .executeUpdate();
(Taken from mkyong)
You are constructing a string that contains the query. The database has no idea how the string is being constructed. Eventually, you'll just pass the string where it will be parsed, compiled, and executed. So yes, you can construct the query this way.
You cannot pass column names or table names as parameters into a query. It is recommended that you pass other values as parameters into the query.

preparedstatement batch fo insert and update?

i have query = "select * from user_message where username = 'john777#gmail.com';" . There is a column 'is_read'( When message is sent to user , is_read is false by default , it means user has not read message yet), after first selection i have to change that column to true UPDATE user_message
SET is_read=true where username = 'john777#gmail.com'; Which means user has read message . so question is can i make one query and execute it throught batch or should i make two different queries ? Which way is better ?
You are write one method with two parameters username and is_read. You can call this method any-time when you needed.
I think your update statement is incorrect since it doesn't pass a message id
I'm guessing it's something like:
UPDATE user_message
SET is_read=true
where username = 'john777#gmail.com'
and user_message_id = 123
If you'd like to set multiple messages to read you could do this via:
UPDATE user_message
SET is_read=true
where username = 'john777#gmail.com'
and user_message_id in (123, 234, 456)
This feels like a design flaw to me. Why does the user_message table have the email? What happens if the user changes their email? You should really decouple the email from the user by giving each user a unique (integer) id which you use as a foreign key.
Based on the assumption the you have a Collection of parameters say emails, I would suggest the following:
String sql = "Your statement";
PreparedStatement stmt = conection.prepare(sql);
for(String email : emails){
stmt.setString(1, email);
stmt.executeUpdate();
stmt.clearParameters();
}
This I think will help you.

Insert integer from a jsp form into a database table?

See my code below...
//connect
//reading params from the form
String name = request.getParameter("name");
String year_prime = request.getParameter("year");
int year = Integer.parseInt(year_prime);
//inserting the params into table Students
stmt.executeUpdate("insert into students(name,year) values('"+name+"', year)");
//close connection
I am trying to get the year value, which is an int, and insert it into a database table. However I am getting an error, and the INSERT methods only seem to work with Strings. Could someone please help me with this problem.
You should have to use PreapredStatement. From your post I can see you have incorrect value for VALUES() set.
stmt.executeUpdate("insert into students(name,year) values ('" + name + "'," + year ")");
It will be easy and safe to perform database operation with PreparedStatement:
String sql="insert into students(name,year) values (?,?)";
PreparedStatement statement=cn.prepareStatement(sql);
statement.setString(1,name);
statement.setInt(2,year);
statement.executeUpdate();
The following links might help you with the basics and also with a working example:
http://www.tutorialspoint.com/jdbc/jdbc-statements.htm
http://www.tutorialspoint.com/jdbc/statement-object-example.htm
Though I won't recommend and it is also not a general practice to include JDBC connection code in JSP, why? Here is the Servlets and Jsp Best Practices for you.
Hope this helps.
Use a PreparedStatement instead of a regular Statement. Also, use executeQuery() instead of executeUpdate().

remove duplicate values while insertion

Hi I am trying to insert values from excel sheet into SQL Database in java. SQL database has already some rows inserted by some other techniques. Now I need to insert new rows from excel sheet and should eliminate the duplicate values which are existed in the database as well as in the excel sheet. For that I write a query like this.
First I inserted the records from excelsheet into SQL database by using insert query
Statement.executeUpdate(("INSERT INTO dbo.Company(CName,DateTimeCreated) values
('"+Cname”' ,'"+ts+"');
Later I deleted the duplicate values using delete query.
String comprows="delete from dbo.Company where Id not in"
+ "(select min(Id) from dbo.Company "
+ "group by CName having count(*)>=1)";
statement3.executeUpdate(comprows);
where Id is autoincremented integer.
but it is not good to do insert and then delete.
How do I know the values are already exist? If it is exist how do I remove during insertion???
You can simply fire a SELECT for the CName first. If a record is found, update else insert a new record.
Edited to add code snippet:
ResultSet rs = Statement.query("SELECT Id from dbo.Company where CNAME = '" +Cname + "'");
if(rs.next()) {
// retrieve ID from rs
// fire an update for this ID
} else {
// insert a new record.
}
Alternatively, if you think that there are already duplicates on your table and you want to remove them as well..
ResultSet rs = Statement.query("SELECT Id from dbo.Company where CNAME = '"+Cname + "'");
List idList = new ArrayList();
while(rs.next()) {
// collect IDs from rs in a collection say idList
}
if(!isList.isempty()) {
//convert the list to a comma seperated string say idsStr
Statement.executeUpdate("DELETE FROM dbo.Company where id in ("+ idsStr + ")");
}
// insert a new record.
Statement.executeUpdate(("INSERT INTO dbo.Company(CName,DateTimeCreated) values('"+Cname”' ,'"+ts+"');
Of course good practice is to use PreparedStatement as it would improve performance.
PS: Excuse me for any syntax errors.
One option would be to create a temp table and dump your Excel data there. Then you can write an insert that joins the temp table with the dbo.Company table and only insert the records that aren't already there.
You could do a lookup on each record you want to insert but if you are dealing with large volumes that's not a super efficient way to do it since you will have to do a select and an insert for each record in you excel spreadsheet.
Merge statements are pretty effective in these types of situations as well. I don't think all databases support them (I know Oracle does for sure). A merge statement is basically a combo insert and update so you can do the look up to the final table and insert if not found and update if found. The nice thing about this is you get the efficiency of doing all of this as a set rather than one record at a time.
If you can control the DB schema, you might consider putting a unique contraint for whatever column(s) to avoid duplicating. When you do your inserts, it'll throw when it tries to add the dup data. Catch it before it tosses you all the way out.
It's usually good to enforce constraints like this on the DB itself; that means no one querying the database has to worry about invalid duplicates. Also, optimistically trying the insert first (without doing a separate select first) might be faster.

Categories