I would like to add a date value from JXDatePicker into my SQL database, however I'm getting this error when running it:
java.sql.sqldataexception: the syntax of the string representation of a datetime value is incorrect
This is my code:
try {
String url = "jdbc:derby://localhost:1527/Members";
String username = "admin1";
String password = "admin1";
Connection con = DriverManager.getConnection(url, username, password);
Statement stmt = con.createStatement();
String query = "INSERT INTO BOOKING(MEMBERID, NAME, CONTACT, "
+ "EMAILADDRESS, RESERVATIONDATE, RESERVATIONTIME) "
+ "VALUES('"+txtMemberID.getText()+"', '"+txtName.getText()+"', "
+ "'"+txtContact.getText()+"', '"+txtEmail.getText()+"', "
+ "'"+comboDate.getDate()+"', '"+comboTime.getSelectedItem()+"')";
stmt.execute(query);
JOptionPane.showMessageDialog(null, "Booking created");
txtMemberID.setText(null);
txtName.setText(null);
txtContact.setText(null);
txtEmail.setText(null);
comboDate.setDate(null);
comboTime.setSelectedItem("00");
}
catch(SQLException ex) {
JOptionPane.showMessageDialog(null, ex.toString());
}
The datatype specified for the Date attribute in my database is Date.
Thank you.
Your problem is that you're trying to embed a Date value (or a String representation of one) into the INSERT statement. Instead of concatenating variables into the query literal, you should use parameterized SQL through a PreparedStatement. In addition to protecting your code from SQL injection, parameterized statements are re-usable by the database, which means that the DB doesn't need to parse the SQL before each execution -- this is especially important if you're running a large number of queries in a loop.
Another thing that you should take care of, is closing the resources you've opened. In your example code, the Connection and Statement are left open after they are no longer needed. This is easy to fix using the try-with-resources statement, which was introduced in Java 7. The resources declared within the try clause get automatically closed after the statement is executed.
Putting it all together, here's an example of what the modified code could look like:
String query = "INSERT INTO BOOKING(MEMBERID, NAME, CONTACT, "
+ "EMAILADDRESS, RESERVATIONDATE, RESERVATIONTIME) "
+ "VALUES(?, ?, ?, ?, ?, ?)";
try (Connection con = DriverManager.getConnection(url, username, password);
PreparedStatement ps = con.prepareStatement(query)) {
ps.setString(1, txtMemberID.getText());
ps.setString(2, txtName.getText());
ps.setString(3, txtContact.getText());
ps.setString(4, txtEmail.getText());
ps.setDate(5, new java.sql.Date(comboDate.getDate().getTime()));
ps.setString(6, comboTime.getSelectedItem().toString());
ps.executeUpdate();
JOptionPane.showMessageDialog(null, "Booking created");
/*clear the UI components etc.*/
} catch(SQLException ex) {
JOptionPane.showMessageDialog(null, ex.toString(), JOptionPane.ERROR_MESSAGE);
}
Related
I am writing the code for a sign-up page for a system. Once the button is clicked, the system will check if the user is above the age of 14. If true, the system should save all the inputted data into a SQL Database.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
int age = Integer.parseInt(Age_Input.getText());
String firstname = FirstName_Input.getText();
String surname = Surname_Input.getText();
String email = Email_Input.getText();
String userid = UserID_InputSignUp.getText();
char[] pass = Password_InputSignUp.getPassword();
if (age<14) {
JOptionPane.showMessageDialog(null,"Sorry, You need to be at least 14 years to use this software... ");
new Login_Page().setVisible(true);
this.setVisible(false);
} else {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connect = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/user_info", "root", "nerdswonka");
Statement stmt = connect.createStatement();
String query1 = "INSERT INTO user_info(user_id, password, firstname, lastname, emailid, age) VALUES('"+userid+"', "+Arrays.toString(pass)+", '"+firstname+"', '"+surname+"', '"+email+"', "+age+");";
stmt.executeUpdate(query1);
JOptionPane.showMessageDialog(null, "Account Creation succesful!");
stmt.close();
connect.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "Error in connecting to SQL Database");
}
new Login_Page().setVisible(true);
this.setVisible(false);
}
}
The code isn't updating anything into the database and is simply showing JOptionPane after an exception (error ) comes. What edits can be done to the code so that values get stored into SQL?
The immediate cause of the failure is probably that your INSERT statement contains the following string which is not being single quoted:
Arrays.toString(pass)
However, you should completely abandon your current approach and instead use a prepared statement:
String sql = "INSERT INTO user_info (user_id, password, firstname, lastname, emailid, age) " +
"VALUES (?, ?, ?, ?, ?, ?)";
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/user_info", "root", "nerdswonka");
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, userid);
ps.setString(2, Arrays.toString(pass));
ps.setString(3, firstname);
ps.setString(4, surname);
ps.setString(5, email);
ps.setInt(6, age);
int row = ps.executeUpdate();
System.out.println(row); // rows inserted (should be 1)
}
catch (SQLException e) {
System.err.format("SQL State: %s\n%s", e.getSQLState(), e.getMessage());
}
catch (Exception e) {
e.printStackTrace();
}
}
Prepared statements do many things, one of which is handling the messy details about how to properly escape your literal data in a SQL query. In this case, they free you from having to worry about placing single quotes around your interpolated Java strings. Statements also prevent bad things like SQL injection from happening.
You are not printing your exception in catch block. You can use e.printStackTrace(); to print exception first.
Here is the code:
public static Connection getConnection() throws Exception {
String name1 = "Danny";
String city1 = "Wien";
try {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/supermarket??verifyServerCertificate=false&useSSL=true";
String username = "myuser";
String password = "mypass";
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
String sql = "insert into marketinfo "
+ " (name, country)" + " values (" + name1 + ", " + city1 + ")";
Statement insertie = conn.prepareStatement(sql);
insertie.executeUpdate(sql);
} catch (Exception e) {
System.out.println(e);
}
return null;
}
My error is "Unknown column 'Danny' in 'field list'" .
In Sql database my table contains id, name and city. I want to pass the id field because that id is incremented automatically.
There's alot going on in that code, and as others have suggested you should break it up. But actually performing the query can be done like this:
public class YourClass {
private static final String SQL = "INSERT INTO marketinfo (name, country) VALUES (?,?)";
public void addMarketInfo(String name, String city) {
try (Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(SQL)) {
stmt.setString(1, name);
stmt.setString(2, city);
stmt.executeUpdate();
} catch (SQLException e) {
// This is fine for debugging, but you probably want to log this or throw an exception
// Depends on how the rest of your application is set up
e.printStackTrace();
}
}
}
All your code creating the connection should most likely get moved to another class, and then called by the getConnection() method as in my example.
If you're using JDBC, PreparedStatements are used ALOT. It's worth looking more more examples on how they are used. Among other benefits, they're really helpful for avoiding string concatenation bugs like your original question.
This is the wrong way to do it. You should learn about PreparedStatement and how to bind values to parameters.
But it's worse than that.
Your method is getConnection, but it's also performing the query. Methods should do one thing well.
You don't close any of your resources. Another bad idea.
You print a stack trace to the console. Better to log it.
You hard wire your connection parameters instead of passing them in.
There's no connection pooling here.
seems you missed inner quotes around var name1 and city1
String sql = "insert into marketinfo "
+ " (name, country)" + " values ('"+ name1 +"', '"+ city1 +"')";
but most important you should use parametrized query instead of string concat .
To fix this you need to quote your variables in the SQL:
String sql = "insert into marketinfo "
+ " (name, country)" + " values ('"+ name1 +"', '"+ city1 +"')";
However, this is awful code, and you should not do it like this.
See here for why not: https://www.acunetix.com/websitesecurity/sql-injection/
As a hit, your sql should look like this:
String sql = "insert into marketinfo "
+ " (name, country)" + " values (:name, :city)";
Then, you use a prepared statement to set the values. Code like this is why websites get all their private information stolen.
String or varchar type should be between two quotes 'some string', but this still not secure so to avoid Syntax errors (Like you have now) or SQL Injection it's better to use PreparedStatement :
String sql = "insert into marketinfo (name, country) values (?, ?)";
try(PreparedStatement insertie = con.prepareStatement(sql);){
insertie.setString(1, name1);
insertie.setString(2, city1);
insertie.executeUpdate();
//...
}
I'm currently trying to write a txt file to a mySQL database through a Java program. My database connects correctly through a JDBC driver and I can create tables etc through the program. However when I try to read the text file in I get this error message
java.sql.SQLException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''FName' , 'SName' , 'DOB') VALUES ('John' , 'McCullough' , '270696')' at line 1
I can't find an error in my SQL code. Here is the rest of the code from the class. Any help would be greatly appreciated.
try (Connection con = DriverManager.getConnection(dbUrl, dbUsername, dbPassword)) {
FileReader file1 = new FileReader("resources/Test.txt");
BufferedReader buffer1 = new BufferedReader(file1);
String read;
while ((read = buffer1.readLine()) != null) {
String[] row = read.split(",");
String fName = row[0];
String sName = row[1];
String DOB = row[2];
String insert = "INSERT INTO chessleague.table1 ('FName' , 'SName' , 'DOB') VALUES ('" + fName + "' , '" + sName + "' , '" + DOB + "')";
ps = con.prepareStatement(insert);
ps.executeUpdate();
ps.close();
}
} catch (Exception ex) {
System.out.println(ex);
}
As mentioned in the comments, don't quote the column names.
The code heavily misuses prepared statements to execute simple SQL. The Connection Class has a createStatement() method that creates a simple statement which is meant for text form SQL commands.
Statement stmt = con.createStatement();
stmt.execute("SELECT * from test.t1");
Prepared statements expect a template that is used to create the SQL statements. Here's an example of how the insert could be done with prepared statement commands.
try (PreparedStatement ps = con.prepareStatement("INSERT INTO chessleague.table1 (FName , SName , DOB) VALUES (?, ?, ?)")) {
ps.setString(0, fName);
ps.setString(1, sName);
ps.setString(2, DOB);
ps.execute();
} catch (SQLException ex) {
System.out.println("SQLException: " + ex.getMessage());
}
Hi I've been trying to insert a string into a sqlite database through java. but the string parameter I'm passing in the values sql statement has quotation marks in it as content. I'm thinking that is the error I'm getting why it isn't inserting into the database. is there a way to bypass the quotation marks in the insert statement. thank you.
this is the code:
public void addNote(String topicadd, String contentadd) throws Exception
{
try
{
getConnection();
statement = conn.createStatement();
statement.executeUpdate("insert into tbl_notes (notes_topic, notes_content) values ('" + topicadd + "', '" + contentadd +"')");
System.out.println("inserted note");
}
catch (Exception m)
{`enter code here`
System.out.println("error insert topic");
System.out.println(m.getMessage());
}
}
this is the parameter kind of long... this is all in contentadd
import java.sql.*;
Resultset rset = null; (this has no new ResultSet() initialization)
Connection conn = null; (this has no new initialization too...)
Statement statement = null; (this has now new initialization)
always.....
try
{
}
catch (Exception e) <- can switch e for any other alphabet
{
e.getMessage();
System.out.println("error this module"); <- personal practice
throw e;
}
- getting connection
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection("jdbc:sqlite:m.db");
*** this is sqlite connection format 'm.db' is the database name
establish connection first..
statement syntax follows:
statement = conn.createStatement();
rset = statement.executeQuery("select * from tbl_notes");
- executeQuery is used for SELECT sql statements
rset = statement.executeUpdate("insert into tbl_notes (ID, status) values
('100', 'status here');
the whole text is in string contentadd, I'm making a short note-taking program... Well, it doesn't execute the insert statement... error somewhere near (word from text) on command prompt... I'm using sqlite... Please let me know if you need more detail. thank you again.
Use a PreparedStatement to insert values containing special characters:
getConnection();
PreparedStatement statement = conn.prepareStatement("insert into tbl_notes (notes_topic, notes_content) values (?, ?)");
statement.setString(1, topicadd);
statement.setString(2, contentadd);
statement.executeUpdate();
As you see you can use parameters with a PreparedStatement which can contain also quotation marks.
Also you get some protection against SQL injection because the Strings given to a PreparedStatement are escaped accordingly.
I have to use JDBC to write to a database (hibernate/ibatis is not an option) and my database is Oracle 11g.
I create the following query: insert into user(user_id, username, age, creation_ts) values(seq_userid.NEXTVAL, 'Jack', 19,TO_TIMESTAMP('14/12/2010 15/09/46', 'DD/MM/RR HH24/MI/SS'));
However my statetement.execeuteUpdate(above sql). generates an invalid sign exception.
But when I perform the query in squirrel it gets commited just fine.
Does anyone know why this is happening?
Edit:
user table:
id: number : not null
username varchar2(30) not null
age number(10) not null
creation_ts timestamp not null
Error:
ORA-00911: invalid character
Java snippet:
try
{
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
String url = "privatized";
Connection conn = DriverManager.getConnection(url, "username", "password");
Statement st = conn.createStatement();
Format formatter = new SimpleDateFormat(dateTimeFormatString);
String formattedDate = formatter.format(Calendar.getInstance(TimeZone.getDefault()).getTime());
StringBuilder insertQuery = new StringBuilder("insert into user(user_id, username, age, creation_ts) values(seq_userid.NEXTVAL,");
insertQuery.append(username);
insertQuery.append(",");
insertQuery.append(age);
insertQuery.append(",TO_TIMESTAMP('");
insertQuery.append(formattedDate);
insertQuery.append("', 'DD/MM/RR HH24/MI/SS'));");
System.err.println(insertQuery.toString());
st.executeUpdate(insertQuery.toString());
conn.close();
} catch (SQLException ex){
System.err.println(ex.getMessage());
System.err.println(ex.getCause().toString());
ex.printStackTrace();
System.out.println("=========================================");
} catch(Exception ex) {
System.err.println(ex.getMessage());
}
As I put in a comment above, the issue could be due to the extra Semicolon at the end of your SQL statement. see this article
You may also want to look at PreparedStatments to make your life easier. Here would be a rough translation of your above code. I have left some parts, and there are most likely errors.
String query = "insert into user(user_id, username, age, creation_ts) values(?,?,?,?)";
PreparedStatement pstmt = conn.prepareStatement(query);
... //fill in all your parameters
pstmt.setTimestamp(4, new Timestamp(System.currentTimeMillis()) );
... //execute here
TO_TIMESTAMP('14/12/2010 15/09/46', 'DD/MM/RR HH24/MI/SS')
You send a 4-digit year but the format string defines a 2-digit year (no century)
Give this a try:
insertQuery.append("', 'DD/MM/RRRR HH24/MI/SS'));");
Are you sure the value of the username variable is 'Jack' and not Jack? (the ORA-00911 error doesn't look like a typical date format error).
Also you should learn about PreparedStatement. They are more efficient, easier to read and debug and not susceptible to SQL injection.
My java is a bit rusty, but this would look something like this with a PreparedStatement:
String query = "insert into user(user_id, username, age, creation_ts) values "
+ "(seq_userid.NEXTVAL, ?, ?, ?)";
Statement st = conn.prepareStatement(query);
st.setString(1, username);
st.setInt(2, age);
st.setTimestamp(3, new java.sql.Timestamp(
Calendar.getInstance(
TimeZone.getDefault()).getTimeMillis()));
st.executeUpdate(insertQuery.toString());
This way you don't need to convert a date to a string to get it converted back by the DB. Also you may find the statement easier to read and you will never have to worry about user's naming their account with a ' (single-quote) :)