So mySQL database keeps accepting duplicate entries despite the unique constraint I've added. I've been trying to look for a similar question but could not find anything related. I don't know if my prepared statement is wrong or if mySQL database is set up wrong. Here is my code:
Connection con = DB.getConnection();
PreparedStatement ps = null, ps1 = null, ps2 = null, ps3 = null, ps4 = null;
ResultSet rs = null;
try {
ps = con.prepareStatement("insert into users(user_id, username, password, email, phone_number,"
+ "name, fb_id, bio) values (DEFAULT, ?, ?, ?, ?, ?, ?, ?)");
ps.setString(1, username);
ps.setString(2, hashedPassword);
ps.setString(3, email_address);
ps.setString(4, phone_number);
ps.setString(5, name);
ps.setString(6, fb_id);
ps.setString(7, bio);
ps.execute();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
ps.close();
con.close();
} catch (Exception e) {
e.printStackTrace(); }
my table has the following columns:
user_id int(11) PRIMARY,
username varchar(20) UNIQUE,
password varchar(100),
email varchar(30) UNIQUE,
phone_number varchar(10) UNIQUE,
fb_id varchar(20) UNIQUE,
bio FULL TEXT
I've created the table using phpmyadmin and username and fb_id correctly gives me the MySQLIntegrityConstraintViolationException, but email and phone_number does not give me any errors when inserting duplicate entries. Is there any reason why this would happen? I am pretty lost as to why the unique constraint is not being enforced...
PS. First time posting!
EDIT: Here is the results of SHOW CREATE TABLE users:
CREATE TABLE users (
user_id int(11) NOT NULL AUTO_INCREMENT,
username varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
password varchar(100) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
email varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
phone_number varchar(10) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
name varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
fb_id varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
bio text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
PRIMARY KEY (user_id),
UNIQUE KEY username (username,email,phone_number),
UNIQUE KEY fb_id (fb_id)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=latin1
You currently have your UNIQUE KEY setup as a composite key.
UNIQUE KEY username (username,email,phone_number)
This means that the combination of username, email and phone number must be unique. It is not specifying each individual column can't contain duplicate values.
For that you should add a UNIQUE INDEX to those columns individually where required. For example to make the email field a UNIQUE INDEX:
ALTER TABLE users ADD UNIQUE INDEX(email);
Related
I am facing a strange problem when I try to update a certain row in my table.
I am using the Connection class from java.sql library. Following is my table script:
CREATE TABLE `crd_web_request` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`order_id` varchar(30) NOT NULL,
`trn_notes` varchar(200) DEFAULT NULL,
`trn_date` date NOT NULL,
`amount` double(20,3) DEFAULT '0.000',
`other_amount` double(20,3) DEFAULT '0.000',
`card_fees` double(20,3) DEFAULT '0.000',
`shipping_fees` double(20,3) DEFAULT '0.000',
`sys_trtype_id` int(11) DEFAULT NULL,
`crd_agent_mast_id` int(11) DEFAULT '0',
`sys_phase_id` int(11) DEFAULT '0',
`sys_user_id` int(11) DEFAULT NULL,
`cust_aname` varchar(250) DEFAULT NULL,
`cust_ename` varchar(250) DEFAULT NULL,
`sys_nationality_id` int(11) DEFAULT NULL,
`passport_id` varchar(45) DEFAULT NULL,
`sys_doc_type_id` int(11) DEFAULT NULL,
`cust_doc_id` varchar(45) DEFAULT NULL,
`cust_email` varchar(250) DEFAULT NULL,
`cust_address` varchar(250) DEFAULT NULL,
`cust_tel` varchar(30) DEFAULT NULL,
`card_holder_name` varchar(400) DEFAULT NULL,
`status` int(1) NOT NULL DEFAULT '0',
`cardType_ID` int(20) DEFAULT NULL,
`sys_org` int(2) DEFAULT NULL,
PRIMARY KEY (`id`,`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=237 DEFAULT CHARSET=utf8;
and following is my java code to update the table:
Statement stmt = null;
String query = "UPDATE smcpp16.crd_web_request SET status = 1 WHERE order_id = '" + orderId + "'";
try {
stmt = conn.createStatement();
System.out.println(query);
stmt.execute(query);
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
I can it figure out why this is happening. Every time when executing the update statement, the table inserts a new record with the same values of the updated row. Can you please help?
I removed the closing of the connection from this code and the duplication is not happening any more.
I just removed:
conn.close();
It is a practice to close the connection in the finally block, something like this :
try{
// update data
}
catch{
//catch exception
}
finally{
//close connection
conn.close();
}
Let me know if this helps.
Trying to create CRUD application using jdbc and mysql. I have Person.class and two tables in Database:
class Person {
String name;
String surname;
List<String> phones;
}
Tables:
`phone`
(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`owner` INT UNSIGNED NOT NULL,
`number` VARCHAR(50) NOT NULL,
CONSTRAINT `PK_phone` PRIMARY KEY (`id`)
)
`person`
(
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`surname` VARCHAR(150) NOT NULL,
`name` VARCHAR(150) NOT NULL,
CONSTRAINT `PK_phonebook` PRIMARY KEY (`id`)
)
ALTER TABLE `phone`
ADD CONSTRAINT `FK_phone_person`
FOREIGN KEY (`owner`) REFERENCES `person` (`id`) ON DELETE Cascade ON UPDATE Cascade
;
SET FOREIGN_KEY_CHECKS=1 ;
How i can add person with field List phones to database using Servlets???
For example: Harry Smith +37521987902
+56727172713
+45679012214
The idea is simple, you can use this way
Insert your person
get the id of that person
insert the list of phone
You can use it like this :
try {
Class.forName(driver);
Connection connection = DriverManager.getConnection(DB_URL, DB_username, DB_password);
String query = "INSERT INTO person (surname, name) values(?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, "hello");
preparedStatement.setString(2, "jdbc");
int affectedRows = preparedStatement.executeUpdate();
long id = 0;
if (affectedRows > 0) {
ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
if (generatedKeys.next()) {
id = generatedKeys.getLong(1);
} else {
throw new SQLException("Creating user failed, no ID obtained.");
}
}
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement("INSERT INTO phone (owner, number) values(?, ?)");
for (String phone : listePhone) {
preparedStatement.setLong(1, id);
preparedStatement.setString(2, phone);
ps.addBatch();
}
ps.executeBatch();
connection.commit();
}
You can learn how to execute multiple statement in one shot, using statement-batching
This question already has answers here:
How to use dynamic table name in SELECT query using JDBC
(3 answers)
Closed 6 years ago.
String sql2 = "create table ? ( id int not null auto_increment, fullname
varchar(30) not null, primary key (id) )";
PreparedStatement stmt2 = conn.prepareStatement(sql2);
stmt2.setString(1, username);
stmt2.execute();
stmt2.close();
from above statements, i got error message('john' as table name):
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 ''john' ( id int not null
auto_increment, fullname varchar(30) not null, primary ' at line 1
eclipse says the error is in this line:
stmt2.execute();
please help guys...tq
You can't use a parameter for the table name in a CREATE TABLE statement.
Instead simply build the SQL string using the variable:
String sql2 = "create table " + username + " ( id int not null auto_increment, fullname
varchar(30) not null, primary key (id) )";
Statement stmt2 = conn.createStatement();
stmt2.executeUpdate(sql2);
this is my Table vehicletlb !
Field Type
v_branch varchar(255) NULL
v_segment varchar(255) NULL
v_company varchar(255) NULL
v_name varchar(255) NULL
v_plateno varchar(255) NULL
v_seats int(11) NULL
v_fuel varchar(255) NULL
v_priceperkm int(11) NULL
v_driver varchar(255) NULL
Now I am trying to Update the table using Prepared Statement in Servlet. But unfortunately it is giving error for unknown column:v_plateno
Also the update query is working fine for other Tables in the database
public void updateVehicle(Vehicle vehicle) {
String updateQuery = "UPDATE vehicletlb SET v_branch=?, v_segment=?, v_company=?, v_name=?, v_seats=?, v_fuel=?, v_priceperkm=?, v_driver=? WHERE v_plateno = ? ";
try {
pStmt = dbConnection.prepareStatement(updateQuery);
pStmt.setString(1, vehicle.getVbranch());
pStmt.setString(2, vehicle.getVsegment());
pStmt.setString(3, vehicle.getVcomp());
pStmt.setString(4, vehicle.getVname());
pStmt.setInt(5, vehicle.getVseats());
pStmt.setString(6, vehicle.getVfuel());
pStmt.setInt(7, vehicle.getVprice());
pStmt.setString(8, vehicle.getVdriver());
pStmt.setString(9, vehicle.getVplateno());
pStmt.executeUpdate();
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
I am using Apache Tomcat 7.0
But it gives error
Unknown column 'v_plateno' in 'where clause'
How can I solve it !!!!
There were no errors in the program and now
I tried Refreshing the Browser, and it started working
Thanks for support !
I am having problems adding data to my database when I am adding "ALTER TABLE" to my tables. I am getting the information from a web page I am working on and is written to a java method that transfers the information to my Database. Everything works fine if I don't use the two ALTER TABLE sentences, but as soon they are added the information will no longer go to my Database. What am I doing wrong? The CREATE TABLE and Java method is listed below. Hope someone can help me!
CREATE TABLE role(
username VARCHAR(15) NOT NULL,
password VARCHAR(15) NOT NULL,
role VARCHAR(6) NOT NULL,
CONSTRAINT username_pk PRIMARY KEY (username)
);
CREATE TABLE customer(
orgnumber INTEGER NOT NULL,
companyname VARCHAR(20) NOT NULL,
contactperson VARCHAR(20),
streetname VARCHAR(30) NOT NULL,
zipcode INTEGER NOT NULL,
city VARCHAR(15) NOT NULL,
phone CHAR(12),
email VARCHAR(30) NOT NULL,
username VARCHAR(15),
CONSTRAINT orgnumber_pk PRIMARY KEY (orgnumber)
);
CREATE TABLE place(
zipcode INTEGER NOT NULL,
city VARCHAR(15),
streetname VARCHAR(30),
CONSTRAINT place_pk PRIMARY KEY (zipcode)
);
ALTER TABLE customer
ADD CONSTRAINT role_fk1 FOREIGN KEY (username)
REFERENCES role;
ALTER TABLE customer
ADD CONSTRAINT place_fk1 FOREIGN KEY (zipcode)
REFERENCES place;
Java method:
public boolean regNewRegister(RegBean newRegister) {
PreparedStatement sqlnewRegister = null;
PreparedStatement sqlnewRole = null;
PreparedStatement sqlnewPlace = null;
String knd = "Customer";
OpenConnection();
boolean ok = false;
try {
/*
* A transaction is started, uses lock.
*/
if (connection == null) {
System.out.println("Went well");
}
connection.setAutoCommit(false);
sqlnewRegister = connection.prepareStatement("insert into customer (ORGNUMBER, CNAME, CONTACTP, STREETN, ZIPC, CITY, PHONE, EMAIL, USERNAME) values(?, ?, ?, ?, ?, ?, ?, ?, ?)");
sqlnewRegister.setInt(1, newRegister.getOrgNumber());
sqlnewRegister.setString(2, newRegister.getCompanyName());
sqlnewRegister.setString(3, newRegister.getContactPerson());
sqlnewRegister.setString(4, newRegister.getStreetName());
sqlnewRegister.setInt(5, newRegister.getZipCode());
sqlnewRegister.setString(6, newRegister.getCity());
sqlnewRegister.setLong(7, newRegister.getPhone());
sqlnewRegister.setString(8, newRegister.getEmail());
sqlnewRegister.setString(9 newRegister.getUsername());
sqlnewRole = connection.prepareStatement("insert into role (USERNAME, PASSWORD, ROLE) values (?, ?, ?)");
sqlnewRole.setString(1, newRegister.getUsername());
sqlnewRole.setString(2, newRegister.getPassword());
sqlnewRole.setString(3, knd);
sqlnewPlace = connection.prepareStatement("insert into place (ZIPC, CITY, STREETN) values (?, ?, ?)");
sqlnewPlace.setInt(1, newRegister.getZipCode());
sqlnewPlace.setString(2, newRegister.getCity());
sqlnewPlace.setString(3, newRegister.getStreetName());
sqlnewRegister.executeUpdate();
sqlnewRole.executeUpdate();
sqlnewPlace.executeUpdate();
connection.commit();
/*
* Transaction ended
*/
ok = true;
} catch (SQLException e) {
Cleaner.rollBack(connection);
String sqlStatus = e.getSQLState().trim();
String statusclass = sqlStatus.substring(0, 2);
if (statusclass.equals("23")) { // Standard code for "integrity constraint violation"
ok = false; // This orgnumber is already registered
} else {
Cleaner.writeMessage(e, "WriteToDB");
}
} finally {
Cleaner.settAutoCommit(connection);
Cleaner.closeSentence(sqlnewRegister);
Cleaner.closeSentence(sqlnewRole);
Cleaner.closeSentence(sqlnewPlace);
}
closeConnection();
return ok;
}
You'll have to insert the role and place before you can insert the customer, as otherwise your referential integrity will be violated.
The two ALTER TABLE statements mean that customer.username must have a corresponding value role.username and customer.zipcode must point to a valid place.zipcode.
As you're inserting the customer first, those records won't exist yet.
EDIT:
Changing the order of executeUpdate to
sqlnewRole.executeUpdate();
sqlnewPlace.executeUpdate();
sqlnewRegister.executeUpdate();
should do the trick.
EDIT2:
One thing to note though, your code will fall over if you have two people with the same ZIP code, as your insert to place will violate the primary key if you try adding it twice...