[Java]Error when Inserting SQL, auto increment in the table - userId - java

So I am making a registration page and when I enter all the fields and click signup to submit, enterNewUser(,,,) is called and the fields userId, username,password and role are inserted into the table User. I confirm this by running select * from user; into MYSQL workbench.
Then enterUsername(,,,) is called and I get this error:
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 '(3,'Barry','Allen')' at line 1
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
'(3,'Barry','Allen')' at line 1
public static int enterNewUser(String username,String password, String role){
//int userId = -1;
int ID = 0;
//int ID=-1;
try{
if(checkUserNameAvailable(username)==true){
Class.forName("com.mysql.jdbc.Driver");
cn = DriverManager.getConnection("jdbc:mysql://localhost/log", "root", "root");
String q0 = "Select userId from user ORDER BY userId DESC LIMIT 1"; //get ID of last
Statement st = cn.createStatement();
ResultSet rs = st.executeQuery(q0);
if(rs.next()){
ID = rs.getInt("userId");
ID++;
}
else
ID=1; // Empty Table, so start with ID 1
rs.close();
st.close();
String q1="insert into user values(?,?,?)";
PreparedStatement ps = cn.prepareStatement(q1);
//ps.setInt(1,ID);
ps.setString(1,username);
ps.setString(2,password);
ps.setString(3,role);
ps.executeUpdate();
ps.close();
}
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
}
DB_close();
//if(userId!=-1)
// return userId;
return -1;
}
public static boolean enterUsername(int userId, String firstname, String lastname){
try{
Class.forName("com.mysql.jdbc.Driver");
cn = DriverManager.getConnection("jdbc:mysql://localhost/log", "root", "root");
//String q1="INSERT INTO user_profile values(?,?,?)";
String q1 = "INSERT into user_profile (userId, firstname, lastname) VALUES (?,?,?)";
PreparedStatement ps = cn.prepareStatement(q1);
ps.setInt(1, userId);
ps.setString (1, firstname);
ps.setString (2, lastname);
ps.executeUpdate();
ps.close();
return true;
}catch(Exception e){
System.err.println(e.getMessage());
e.printStackTrace();
}
DB_close();
return false;
}
Here is my database structure.
Edit: found the issue, database was not structured properly.
CREATE TABLE user ( userId int(3) NOT NULL AUTO_INCREMENT,
username varchar(20) DEFAULT NULL, password varchar(20) DEFAULT
NULL, role varchar(20) DEFAULT NULL, PRIMARY KEY (userId),
UNIQUE KEY username (username) );
CREATE TABLE user_profile ( userId int(3) NOT NULL DEFAULT '0',
firstName varchar(20) DEFAULT NULL, lastName varchar(20) DEFAULT
NULL, PRIMARY KEY (userId), CONSTRAINT FK FOREIGN KEY
(userId) REFERENCES user (userId) );

Shouldn't following section in method enterUsername
ps.setInt(1, userId);
ps.setString (1, firstname);
ps.setString (2, lastname);
be like this
ps.setInt(1, userId);
ps.setString (2, firstname);
ps.setString (3, lastname);

I don't see the reason for the error message that you posted.
But I see some other things that look like a problem:
ps.setInt(1, userId);
ps.setString (1, firstname);
ps.setString (2, lastname);
The indexes are wrong: instead of 1, 1, 2, it should be 1, 2, 3.
(Frankly, I don't see how the code could possibly work as posted.)
Btw, this also looks wrong in the other method:
insert into user values(?,?,?)
As the table has more than 3 columns, you need to specify their names,
like you did in enterUsername.

Use
String q1 = "INSERT into user_profile (firstname, lastname) VALUES (?,?)";
because your first field is auto increment..So it automatically increment values while inserting values.
I recommended this way,
Delete your current table and create a new one like this
id-->int(30) (AUTO INCREMENT) NOTNULL //Dont need to take care of this field
USER_ID-->int(30) NOT NULL //you should create your own ID and increment it before adding a new person
username-->varchar(100)
password-->varchar(100)
role-->varchar(100)
and usually, call userId exactly same like your code,
String q0 = "Select userId from user ORDER BY USER_ID DESC LIMIT 1"; //get ID of last
Statement st = cn.createStatement();
ResultSet rs = st.executeQuery(q0);
if(rs.next()){
ID = rs.getInt("USER_ID ");
ID++;
}

Related

JSP: problems with multiple queries and generated keys

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...

inserting jtextbox value and jradiobutton value to database

I am trying to insert values from textboxes into the database but getting error com.microsoft.sqlserver.jdbc.SQLServerException: String or binary data would be truncated. I thought the problem was with radio button but when I tried to insert value in the database removing radio button and gender from the query, I am getting the same error.
I tried inserting values Name: a, Username:a ,Contact:a , radio button [male], still getting the same error.
I can not find out how I am getting this error.
create table temp (
id int IDENTITY(1,1) PRIMARY KEY,
name varchar(32) not null,
username varchar(32) not null,
contact varchar(32) not null,
gender int
);
btnSubmit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try
{
int gender = 0;
Connection sqlCon = DB_con.getSQLConnection();
PreparedStatement ps = sqlCon.prepareStatement(
"insert into temp (name, username, contact, gender) values ( ?, ?, ?, ?)"
);
ps.setString(1, txtName.toString());
ps.setString(2, txtUserName.toString());
ps.setString(3, txtContact.toString());
gender = (rbtnMale.isSelected()) ? 1 :2;
System.out.println("value of gender " + gender );
ps.setInt(4, gender);
int i = ps.executeUpdate();
System.out.println("records inserted: "+i);
sqlCon.close();
}
catch(Exception e)
{
System.out.println(e.toString());
}
}
});
It's likely that one of these:
txtName.toString()
txtUserName.toString()
txtContact.toString()
...is longer then 32 characters. Why not log them somewhere before you do the insert so you can see?
It's not clear what class these objects are from your code snippet. Is it possible that they're the default toString() method implementation of JTextField? If so, use getText(), not toString().
Change
ps.setString(1, txtName.toString());
ps.setString(2, txtUserName.toString());
ps.setString(3, txtContact.toString());
to
ps.setString(1, txtName.getText());
ps.setString(2, txtUserName.getText());
ps.setString(3, txtContact.getText());
toString is doing a debug dump of the controls, which definitely longer than 32 characters and doesn't represent the text typed into the field (or at least not in a format you want ;))

Error PLS-00201 Identifier 'REG_PACK.DELUSER' must be declared

I'm getting an error stated above.
I've tried granting the user to execute but no luck.
Here's my SQL code:
create or replace PACKAGE BODY reg_pack AS PROCEDURE ADDUSER( c_fname IN user_profile.firstname%type, c_lname IN user_profile.lastname%type, c_cnum IN user_profile.contactno%type, c_dob IN USER_PROFILE.DOB%type, c_address IN user_profile.address%type, c_city IN user_profile.city%type, c_state IN user_profile.state%type, c_country IN user_profile.country%type, c_email IN user_profile.emailid%type, c_password IN user_profile.password%type, c_usertype IN user_profile.usertype%type, c_username IN user_profile.username%type) IS BEGIN INSERT INTO USER_PROFILE (userid,firstname ,lastname,contactno,dob,address,city,state ,country,emailid,password,usertype,username) VALUES (userid_seq.NEXTVAL, c_fname, c_lname, c_cnum, c_dob, c_address, c_city, c_state, c_country, c_email, c_password, c_usertype, c_username); END ADDUSER;
PROCEDURE DELUSER(c_id IN user_profile.userid%type) IS BEGIN DELETE FROM USER_PROFILE WHERE user_profile.userid = c_id; END DELUSER;
PROCEDURE SELECTUSER(c_id IN user_profile.userid%type, c_fname OUT user_profile.firstname%type, c_lname OUT user_profile.lastname%type, c_cnum OUT user_profile.contactno%type, c_dob OUT USER_PROFILE.DOB%type, c_address OUT user_profile.address%type, c_city OUT user_profile.city%type, c_state OUT user_profile.state%type, c_country OUT user_profile.country%type, c_email OUT user_profile.emailid%type, c_password OUT user_profile.password%type, c_usertype OUT user_profile.usertype%type, c_username OUT user_profile.username%type) AS BEGIN
SELECT FIRSTNAME ,LASTNAME ,CONTACTNO ,DOB ,ADDRESS ,CITY ,STATE , COUNTRY ,EMAILID ,PASSWORD ,USERTYPE ,USERNAME INTO c_fname, c_lname, c_cnum, c_dob, c_address, c_city, c_state, c_country, c_email, c_password, c_usertype, c_username
FROM USER_PROFILE
WHERE user_profile.userid = c_id; END SELECTUSER;
END reg_pack;
As you can see there are three procedures namely DELUSER, ADDUSER and SELECTUSER. I'm using JDBC to execute these queries, the ADDUSER query worked but the other two returned PLS-00201.
Here's my JAVA code:
For insert:
sql2 = "{call REG_PACK.ADDUSER(?,?,?,?,?,?,?,?,?,?,?,?)}";
callable = con.prepareCall(sql2);
callable.setString(1, fname);
callable.setString(2, lname);
callable.setString(3, cnum);
callable.setString(4, dob);
callable.setString(5, address);
callable.setString(6, city);
callable.setString(7, state);
callable.setString(8, country);
callable.setString(9, email);
callable.setString(10, password);
callable.setString(11, utype);
callable.setString(12, username);
callable.executeQuery();
for delete:
int userID = Integer.parseInt(jTextField1.getText());
System.out.println(userID);
try{
String sqlDelete = "{CALL REG_PACK.DELUSER(?)}";
callable = con.prepareCall(sqlDelete);
callable.setInt(1, userID);
callable.executeQuery();
JOptionPane.showMessageDialog(this, "User deleted!");
}catch(SQLException e){
JOptionPane.showMessageDialog(this, e.getMessage());
}

How to create tables in JavaDB and prepareStatement?

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...

preparedStatement and resultSet interfaces how to use batch and get methods

I am starting now to use the package java.sql and I am doing some experiments with it.
I have these two tables
the first is:
`user` (
`userID` INT NOT NULL AUTO_INCREMENT ,
`nickname` VARCHAR(20) NULL ,
PRIMARY KEY (`userID`) )
and the second is:
`club` (
`clubID` INT NOT NULL AUTO_INCREMENT ,
'clubName` VARCHAR(20) NOT NULL ,
`userID` INT NULL ,
PRIMARY KEY (`clubID`) ,...
where userID is a foreign key associated to the userID of the first table.
And this is the code that should explain what I want to do. (this is only for one user-club)
Class.forName("com.mysql.jdbc.Driver");
this.connect = DriverManager.getConnection("jdbc:mysql://localhost/" + this.database + "?user=" + this.user + "&password=" + this.password);
String s;
s = ("insert into " + this.database + ".user (nickname) values (?)");
this.preparedStatement = this.connect.prepareStatement(s);
this.preparedStatement.setString(1, "username");
this.preparedStatement.executeUpdate();
s = ("SELECT userID from " + this.database + ".user where nickname = 'username'");
this.preparedStatement = this.connect.prepareStatement(s);
this.resultSet = this.preparedStatement.executeQuery();
int n=0;
while (resultSet.next())
{
n = this.resultSet.getInt("userID");
}
s = ("insert into " + this.database + ".club (clubName, userID) values (?, ?)");
this.preparedStatement = this.connect.prepareStatement(s);
this.preparedStatement.setString(1, "club");
this.preparedStatement.setInt(2, n);
this.preparedStatement.executeUpdate();
If I would do this process for more couples (username, clubname), for example saved in an HashMap how could I use the addBatch() method of preparedStatement Inteface??
I should use three batches one for eache action:
1 insertion of username
2 selection (and recording) of userID
3 insertion of clubname associated to the correct userID
Or I could include all the process in only one batch??
And another question, why If i try to remove the while cycle surrounding the resultSet.getInt() method it gives me an error??
Thanks in advance to all who will try to help me!
You cannot include all the process in only one batch. The batch is intended for a single query. Here is the reference link for a good example.
You can execute multiple queries as different batches as follows .
try {
DataSource dataSource = null;// specify data source
Connection con = dataSource.getConnection();
Statement s = con.createStatement();
// or
// PreparedStatement s =
// con.prepareStatement("INSERT INTO profile (fullname) VALUES ('Visruth CV')");
s.addBatch("INSERT INTO tran1 (username, password, profileid) VALUES ('visruth', 'password', 1)");
s.addBatch("INSERT INTO testtab (name) VALUES ('testtab')");
s.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
}
If you remove the while (resultSet.next()) loop, it will make a NullPointerException because the current position of the cursor in the resultSet is in the default row, when you make resultSet.next() the cursor will jump in to the next row if there is a row available (from the default row to first row, first row to second row etc...) and at the same time resultSet.next() will return true (only if it jumps) otherwise false. If resultSet contains more than one row, it can be put inside a while loop, if not just need to use the if condition there.

Categories

Resources