Java problemDatabase Syntax Error at or near ":" - java

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

Related

why does my sql table treat 1000 as a middle number?

When I try to sort by a value descending my SQL table does it correctly, but if it sees for example "1000" it always puts it in the middle?
for Example:
this even happens when I reference it in spigot (I'm using it for a plugin) it outputs it the same way
this is how I'm calling it in my plugin:
PreparedStatement statement = database.getConnection().prepareStatement("SELECT uuid FROM player_stats ORDER BY blocks_broken DESC");
ResultSet rs = statement.executeQuery();
while (rs.next()) {
String name = rs.getString("uuid");
LeaderboardCommand.name = name;
String player = String.valueOf(Bukkit.getPlayer(UUID.fromString(name)));
p.sendMessage(player);
I know it's not perfect as I'm just learning/experimenting with databases currently, but I'm mainly asking for help on why the SQL is outputted this way & advice on any severe mistakes I'm making is greatly appreciated!
Thanks in advance -Occy
public void createPlayerStats(PlayerStats playerStats) throws SQLException {
PreparedStatement statement = getConnection()
.prepareStatement("INSERT INTO player_stats(uuid, blocks_broken, last_login, last_logout) VALUES (?, ?, ?, ?)");
statement.setString(1, playerStats.getPlayerUUID());
statement.setLong(2, playerStats.getBlocksBroken());
statement.setDate(3, new Date(playerStats.getLastLogin().getTime()));
statement.setDate(4, new Date(playerStats.getLastLogout().getTime()));
statement.executeUpdate();
statement.close();
It happens because block_broken type is a varchar and not a number.
In this case you are ordering lexycographically and not numerically.
You can change your query to handle that as a numeric value with an explicit cast so your query should be:
SELECT uuid FROM player_stats ORDER BY cast(blocks_broken as numeric) DESC
Update: In MariaDb try to use this (You can try directly in the db client and once it is working update your java code):
SELECT uuid FROM player_stats ORDER BY CAST(blocks_broken AS INTEGER) DESC

How to format a JDBC PreparedStatment with a $index parameter for Postgres

I am working with a postgres database and I'm using JDBC. Most things are working fine, but I'm getting the following error with this piece of code and it seems to be that I'm not properly using setString/setDate with a $ style parameterized query. Without further ado, here is the code
(The variables not initialized here were initialized correctly ahead of this method call).
String query = "INSERT INTO \"tracks\" (\"artist\", \"album\", \"name\", \"listened_at\", \"created_at\", \"updated_at\", \"url\", \"image_url\") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING \"id\"";
PreparedStatement statement = connection.prepareStatement(query);
java.sql.Date current = new java.sql.Date((new Date()).getTime());
java.sql.Date sqlListenedAt = new java.sql.Date(listenedAt.getTime());
statement.setString(1, artist);
statement.setString(2, album);
statement.setString(3, name);
statement.setDate(4, sqlListenedAt);
statement.setDate(5, current);
statement.setDate(6, current);
statement.setString(7, url);
statement.setString(8, imageUrl);
and the error that I'm getting is as follows
org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.
Is there a way to properly use a INSERT INTO "table" ("column_a", "column_b") VALUES ($1, $2) style statement with JDBC?
String query = "INSERT INTO tracks (artist, album, name, listened_at, created_at, updated_at, url, image_url) VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING id";
I think the rest of your code is probably okay. Two basic comments:
-You only need to quote your table / column names when they are otherwise reserved words in SQL. The way you wrote it is really hard to read.
-JDBC uses ? for placeholders. I've never seen $1 etc. Maybe that works, but I don't think so.

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.

Java Prepared statement not executing

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.

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