Java Prepared statement not executing - java

I have created a small 3 tier program, consisting of : front end -> servlet -> database.
Front end I enter some details into a form. They are passed to a servlet, which will render some HTML and display the values entered into the form, while also calling a class DatabaseHelper. The DatabaseHelper then connects and inserts these same values into a table.
I know the values are being passed to the servlet class ok, as they are being displayed in the HTML. So the problem must lie within the prepared statement. Problem is, I cannot see any fault with the statement itself. When I query the table itself, there is no data there.
Database connectivity is functional, as I can insert values into a database using hardcoded statements, just not a prepared statement.
Here is a look at the statement Im using. Any advice is much appreciated.
public void addRegisterDetails(String name, String email, String country, String password, ){
try{
String driver = "com.mysql.jdbc.Driver";
Class.forName(driver).newInstance();
// Make db connection
con = DriverManager.getConnection(url, USERNAME, PASSWORD);
st = con.createStatement();
String query = " INSERT INTO user_information (name, email, country, password)" + " VALUES (?, ?, ?, ?)";
PreparedStatement preparedStmt = con.prepareStatement(query);
preparedStmt.setString (1, name);
preparedStmt.setString (2, email);
preparedStmt.setString (3, country);
preparedStmt.setString (4, password);
preparedStmt.execute();
}catch(ClassNotFoundException ex) {
System.out.println(ex);
}catch(Exception e){
e.printStackTrace();
}
}
Table definition
id| name | email | country | password
all VARCHAR except the id, which is type INT.

You should invoke the method executeUpdate() on the statement object.
Also, I don't see any call to commit the data, any transaction handling. It's fine if you skipped that piece of code for the purpose of this question; otherwise it's quite an important step ( commit if all goes well, rollback for exception scenarios)

Use executeUpdate for database write operations:
preparedStmt.executeUpdate();

Answer: The database ID was not set to auto increment. For some reason this does not allow you to then insert data to table. Thanks to ChadNC for pointing this out.

Also, why st = con.createStatement();?
And why do you have a leading space in your query?
String query = " INSERT INTO user_information (name, email, country, password)"
+ " VALUES (?, ?, ?, ?)";
This leading space may or may not matter...
Lastly, you should be closing your connection when you're through with it, using try-with-resources or a finally block.

Related

SQLServer Exception: Invalid column name

com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name 'IDPaciente'
I am getting this exception. This is my code:
String query = "INSERT INTO Paciente('IDPaciente', 'NomePaciente', 'IdadePaciente', 'LocalidadePaciente') VALUES('"+IDTextField.getText()+"', '"+NomeTextField.getText()+"', '"+IdadeTextField.getText()+"', '"+LocalidadeTextField.getText()+"')";
try
{
st = con.DatabaseConnection().createStatement();
rs = st.executeQuery(query);
}
I suspect the problem might be in the query itself.
I have searched a lot and couldn't find the solution to my problem. I have tried refreshing the cache, changing permissions within the schema, restarting sql server (I am using sql server management studio 2012), I am correctly connected to my database, and nothing seems to work.
What could I be doing wrong?
Thank you!
Remove quotes , try :
String query = "INSERT INTO Paciente(IDPaciente, NomePaciente, IdadePaciente, LocalidadePaciente) VALUES('"+IDTextField.getText()+"', '"+NomeTextField.getText()+"', '"+IdadeTextField.getText()+"', '"+LocalidadeTextField.getText()+"')";
try
{
st = con.DatabaseConnection().createStatement();
rs = st.executeQuery(query);
}
Remove also quotes for INT values.
Your code is not secure, you can easily get Syntax error or SQL Injection I suggest to use PreparedStatement instead.
You have a problem in your Query, the columns should not be between '' so you can use this instead :
String query = "INSERT INTO Paciente(IDPaciente, NomePaciente, IdadePaciente, "
+ "LocalidadePaciente) VALUES(?, ?, ?, ?)";
try (PreparedStatement insert = con.prepareStatement(query)) {
insert.setString(1, IDTextField.getText());
insert.setString(2, NomeTextField.getText());
insert.setString(3, IdadeTextField.getText());
insert.setString(4, LocalidadeTextField.getText());
insert.executeUpdate();
}
If one of your column is an int you have to use setInt, if date setDate, and so on.
You have four problems, though only the first is giving you the current error:
Single-quotes (') are for quoting text literals, not column names. In MS SQL Server, you can quote column names using double-quotes (") or square brackets ([]), but you don't need to quote them at all.
To prevent SQL Injection attacks, where hackers will steal your data and delete your tables, and to prevent potential syntax errors, never build a SQL statement with user-entered strings, using string concatenation. Always use a PreparedStatement.
Always clean up your resources, preferably using try-with-resources.
Don't use executeQuery() for an INSERT statement. Use executeUpdate(). As the javadoc says:
Executes the SQL statement in this PreparedStatement object, which must be an SQL Data Manipulation Language (DML) statement, such as INSERT, UPDATE or DELETE; or an SQL statement that returns nothing, such as a DDL statement.
So, your code should be:
String query = "INSERT INTO Paciente" +
" (IDPaciente, NomePaciente, IdadePaciente, LocalidadePaciente)" +
" VALUES (?, ?, ?, ?)";
try (PreparedStatement st = con.DatabaseConnection().prepareStatement(query)) {
st.setString(1, IDTextField.getText());
st.setString(2, NomeTextField.getText());
st.setString(3, IdadeTextField.getText());
st.setString(4, LocalidadeTextField.getText());
st.executeUpdate();
}
Remove the quotes from your column names.
"INSERT INTO Paciente(IDPaciente, NomePaciente, IdadePaciente, LocalidadePaciente) VALUES('"+IDTextField.getText()+"', '"+NomeTextField.getText()+"', '"+IdadeTextField.getText()+"', '"+LocalidadeTextField.getText()+"')"
The Column names are does not typed within quotes, Remove them and try again.
Demo:-
Create table MyTable (id int , name varchar (50))
go
insert into MyTable (id,name) values (1 , 'ahmed')
Result:-
(1 row(s) affected)
Try insert them again with quotes.
insert into MyTable ('id','name') values (1 , 'ahmed')
Result:-
Msg 207, Level 16, State 1, Line 3
Invalid column name 'id'.
Msg 207, Level 16, State 1, Line 3
Invalid column name 'name'.

Trouble with retrieving data with prepared statement in DAO [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
public class StudentDAO extends ConnectorDAO {
private List<StudentBean> studentList = new LinkedList<>();
private StudentBean studentBean;
public List<StudentBean> retrieveStudents() {
Connection connection;
try {
String myQuery = "SELECT ?, ?, ? FROM Students";
connection = getConnection() // getConnection() comes from superclass
PreparedStatement preparedstatement = connection.prepareStatement(myQuery);
preparedStatement.setString(1, "firstname");
preparedStatement.setString(2, "lastname");
preparedStatement.setString(3, "studentID");
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
studentBean = new StudentBean();
studentBean.setFirstName(resultSet.getString("firstname"));
studentBean.setLastName(resultSet.getString("lastname"));
studentBean.setID(resultSet.getInt("studentID"));
studentList.add(studentBean);
}
} catch (Exception e) {
// Error handling stuff
} finally {
// close connection, resultset and preparedstatement
}
}
}
An error shows in my eclipse. On the line where I set the studentBean's ID. The data type of the studentID in my database is of Int. I'm not sure how to retrieve it though. Can anyone help me? It works when I use a Statement object when I query with the parameters used in the prepared statement.
Your code for building the query is incorrect:
String myQuery = "SELECT ?, ?, ? FROM Students";
connection = getConnection() // getConnection() comes from superclass
PreparedStatement preparedstatement = connection.prepareStatement(myQuery);
preparedStatement.setString(1, "firstname");
preparedStatement.setString(2, "lastname");
preparedStatement.setString(3, "studentID");
Is not possible:
A query string is formatted like this (example):
String myQuery = "SELECT firstname, lastname, studentID FROM Students WHERE studentID=?";
The parameters are only to be used on variables not on column names, table names etc.
So once you have code like that you could query on a studentID (not your goal but just for the example):
preparedStatement.setInt(1, someStudentID);
Which would be send with the preparedStatement to the DBMS in which then the DBMS replaces the ? with the value of someStudentID.
The meaning of setString (or setInt or any other setXXX in PreparedStatement), is "replace the corresponding question mark with the given value, appropriately typed". So this code:
String myQuery = "SELECT ?, ?, ? FROM Students";
connection = getConnection() // getConnection() comes from superclass
PreparedStatement preparedstatement = connection.prepareStatement(myQuery);
preparedStatement.setString(1, "firstname");
preparedStatement.setString(2, "lastname");
preparedStatement.setString(3, "studentID");
Effectively creates the following query:
SELECT 'firstname', 'lastname', 'studentID' FROM Students
Now, this tells it to select three literal strings from the table. If you ran this query in an SQL command line utility or something similar, you'd find that the result is
firstname | lastname | studentID
firstname | lastname | studentID
firstname | lastname | studentID
firstname | lastname | studentID
...
Instead of what you expected. Anything set by setString is interpreted as a literal string - as if it includes single quotes.
So question marks are used for setting values in the statement, that would be literal values if you were typing the statement in a command line utility.
So what your result set has is rows upon rows containing the three strings firstname, lastname and studentID.
Now, in the next bit of code:
while (resultSet.next()) {
studentBean = new StudentBean();
studentBean.setFirstName(resultSet.getString("firstname"));
studentBean.setLastName(resultSet.getString("lastname"));
studentBean.setID(resultSet.getInt("studentID"));
studentList.add(studentBean);
}
in many database systems, you wouldn't even be able to use getString("firstname") because the returned column name from a query for literals is arbitrary. But I suppose your database system actually gives the return column the same name as the literal value. So you are able to retrieve firstname and lastname (But their content is not the student name! It's the literal strings "firstname" and "lastname"), because you are using getString.
But you run out of luck when you try to use getInt. Since you queried for literal strings, you are getting back three strings. The third column is not an integer but the literal string "studentID". This is where you hit the error.
So you should change your query to
"SELECT firstname, lastname, studentID FROM Students"
Which means you don't necessarily need a prepared statement in this case, but it doesn't hurt either.
Where can you use the question marks, then?
Anywhere you need a literal value in your query. For example, if you want to know the difference between a person's year of birth and a given year, you could write:
SELECT year_of_birth - ? FROM people
And then use setInt(1,1969) or setInt(1,2001) to make the query become:
SELECT year_of_birth - 1969 FROM people
and
SELECT year_of_birth - 2001 FROM people
Respectively. In prepared statements, the actual names of database objects such as columns and tables, which are not literals, cannot be replaced with a question mark. They are part of the query plan itself.

Insert values to mysql table via Java GUI

I'm working with java and mysql and I'm facing a problem. I'm trying to create an app with GUI to insert data into mysql table and this is the code :
public void insertuser(String fullname,String salary,String adress,String username,String password) throws SQLException
{
openconnection();
//openconnection method works well
String queryInsert =
"INSERT INTO hema.employee (Emp_name,Emp_salary,Adress,UserName,PassWord)"
+ "VALUES ('"+fullname+"','"+salary+"','"+adress+"','"+username+"','"+password+"')";
Statement stm=(Statement) con.createStatement();
ResultSet rs;
stm.executeQuery(queryInsert);
}
and in the JFrame class I call this method using this code :
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
String NAME =jTextField1.getText();
String SALARY =jTextField2.getText() ;
String ADRESS =jTextField3.getText();
String USER =jTextField4.getText();
String PASS =jPasswordField1.getText();
Employee emp=new Employee();
emp.insertuser(NAME, SALARY, ADRESS, USER, PASS);
} catch (SQLException ex) {
Logger.getLogger(Register.class.getName()).log(Level.SEVERE, null, ex);
}
}
and the first error I have is:
java.sql.SQLException: Can not issue data manipulation statements with executeQuery().
The executeQuery() method is only for executing select statements. For insert, update, and delete statements, you should use the executeUpdate() method.
Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement or an SQL statement that returns nothing, such as an SQL DDL statement.
String sqlInsert =
"INSERT INTO hema.employee (Emp_name,Emp_salary,Adress,UserName,PassWord)"
+ "VALUES (?, ?, ?, ?, ?)";
try (PreparedStatement stm = con.prepareStatement(sqlInsert)) {
stm.setString(1, fullname);
stm-setBigDecimal(2, new BigDecimal(salary));
stm.setString(3, adress);
stm.setString(4, username);
stm.setString(5, password);
int updateCount = stm.executeUpdate(); // 1 when inserted 1 record
} // Closes stm
The error, that for INSERT, DELETE. UPDATE and such executeUpdate should be used is given already.
Also close the statement, for example use the above try-with-resources.
Important is to use a prepared statement. This is a security measure (against SQL injection), but also escapes quotes and backslashes in the values
Another advantage of a prepared statement is that you could reuse it; not so necessary here.
But more important is the type safe setting of fields: I altered the salary field to use BigDecimal, appropriate for numeric values with decimals (SQL column type DECIMAL or so).

Java problemDatabase Syntax Error at or near ":"

Im using a PostgreSQL database, and when i'm trying to insert the data, it gives me an error problemDatabase error: ERROR syntax error at or near ":" Position 206.
Here is a code for insert query :
public static Model_Customer Insert(String FName, String LName, String Registration, String Make, String Model, String Engine, String Year, String Mileage, String Type, String Date, String Time) throws Exception {
try{
Statement stmt = Model_Customer.conn.createStatement();
ResultSet rs = stmt.executeQuery("INSERT INTO appointment (fname, lname, registration, make, model, engine, year, mileage, type, date, time) VALUES ("+FName+",'"+LName+"','"+Registration+"','"+Make+"','"+Model+"','"+Engine+"','"+Year+"','"+Mileage+"','"+Type+"','"+Date+"',"+Time+") RETURNING appointmentid");
if(rs.next())
return Model_Customer.QueryID(rs.getInt(1));
}catch(Exception e){
throw new Database_Exception(e.getMessage());
}
return null;
}
In Debug it goes okay to the executeQuery and straight after it, it goes to the catch exception and gives an error. Table and columns in the database are there. There's no ":" anywhere in the code except the messages, so im not sure why it goes like this.
Thanks for your answer Joop Eggen I have used you way and had to add
stmt.executeUpdate();
Worked like a charm! Thanks!
PreparedStatement stmt = conn.prepareStatement(
"INSERT INTO appointment (fname, lname, registration, make, model, "
+ "engine, year, mileage, type, \"date\", \"time\") "
+ "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
stmt.setInt(1, FName);
stmt.setString(2, LName);
stmt.setString(3, Registration);
...
int updateCount = stmt.executeUpdate(Statement.RETURN_GENERATED_KEYS);
ResultSet rs = stmt.getGeneratedKeys();
if(rs.next())
return Model_Customer.QueryID(rs.getInt(1));
JDBC offers a database engine independent way to retrieve the generated keys: a result set of inserted rows with the generated keys per row.
RETURN_GENERATED_KEYS is probably not needed. Some field names might be reserved key words, which then need double quotes around them.
About recommending PreparedStatement:
The first remark on every ...+var+... construed statement, will be: use a prepared statement with ... ? .... There are two very important reasons (besides the efficiency of a PreparedStatemen and using BLOBs):
SQL injection, see this;
you can leave out the apostrophes ('), and escaping of apostrophe, backslash etcetera is done for you, and you can pass typesafe parameters (int, java.sql.Date).

Syntax error in Prepared statement while inserting into db

Hi I am trying insert data into the database using prepared statement but I am getting syntax error could u please help
public boolean SignUp(String last_name, String first_name,String email, String password,String confirm_password,String phone){
Connect connect = new Connect();
Connection conn = connect.Connection();
java.sql.PreparedStatement preparedStatement = null;
//NULL is the column for auto increment
String insertQuery = "INSERT INTO users VALUES (NULL, ?, ?, ?, ?, ?, ?)";
preparedStatement = conn.prepareStatement(insertQuery);
preparedStatement.setString(1, last_name);
preparedStatement.setString(2, first_name);
preparedStatement.setString(3, email);
preparedStatement.setString(4, password);
preparedStatement.setString(5, confirm_password);
preparedStatement.setString(6, phone);
int rs = preparedStatement.executeUpdate(insertQuery);
conn.close();
}
here is the error message
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 '?, ?, ?, ?, ?, ?)' at line 1
I found the answer :)
Use preparedStatement.execute() instead of executeUpdate(sql). You have already set the sql and params - the new setting in executeUpdate(sql) overrides the bind.
You should change the statement to list the columns explicitly, and drop NULL from the list of values.
String insertQuery = "INSERT INTO users"
+ " (last_name, first_name, email, password, confirm_password, phone)"
+ " VALUES(?,?,?,?,?,?)";
This way your insert statement is no longer dependent on the order of columns in your users table, and is also immune to addition of columns to the table.
Note that although this design is probably OK for a toy or an education system, but in a real production system storing password in a table is very dangerous. Storing confirm_password is rather unusual, too: normally your system checks that password is the same as confirm_password, and then inserts a salted password hash and a salt into the table.
Just a guess, not I'm not certain. But if one of the fields is autoincrement, then I don't think you need to insert it. Try taking out that NULL....

Categories

Resources