I am trying to insert an email ID to a table in my SQLite3 Database. In my case it successfully creates the table but gives an error while inserting a record in it - "near "#gmail": syntax error". How can i resolve this ? Here is the code -
public void insertData(String emailId, double gtse, long receivedDate) throws ClassNotFoundException, SQLException{
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection("jdbc:sqlite:testdb.sqlite");
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
ResultSet result = statement.executeQuery("SELECT name FROM sqlite_master WHERE type='table' AND name='T1'");
if(!result.next()){
statement.executeUpdate("create table T1 (email TEXT, gtse REAL, receiveddate DATE)");
statement.executeUpdate("insert into T1 values(" + emailId + ", "+ gtse +", "+ receivedDate +")");
}
else{
}
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
try
{
if(connection != null)
connection.close();
}
catch(SQLException e)
{
// connection close failed.
System.err.println(e);
}
}
}
Your core error is that for the insert query you are not enclosing the values to be inserted, in quotes. Your query, after construction, looks something like this:
insert into T1 values(whatever#gmail.com, emailtexthere, 04-07-2013)
When it should be something like this:
insert into T1 values('whatever#gmail.com', 'emailtexthere', '04-07-2013')
The SQL parser chokes while trying to parse your current query, because the syntax is incorrect. The solution to this problem is not simply to enclose the values in quotes though, but rather to use prepared statements. This is because the way you are constructing your query right now is vulnerable to SQL injection attacks. Here is an example of using a prepared statement:
PreparedStatement pStmt = conn.prepareStatement(
"INSERT INTO T1 VALUES(?, ?, ?)");
pStmt.setString(1, emailId);
pStmt.setString(2, gtse);
pStmt.setDate(3, receivedDate);
pStmt.execute();
Related
I'm trying to get the primary auto incremented key from one table and store this in another using MySQL connector and JDBC. Although its giving me this error:
statement.executeupdate() cannot issue statements that produce result
sets.
I think its something to do with the storing of the integer variable but not too sure.
public void insertIntoWorkoutLogs(String field_setNumber, String field_repNumber, String field_weightAmount) {
try{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/workout","root","");
Statement statement =connection.createStatement();
String insert ="INSERT INTO `workout`.`workoutlogs`" + " (`SetNumber`, `RepNumber` , `WeightAmount`)"
+ "VALUES('" +field_setNumber+"','"+field_repNumber+"','"+field_weightAmount+"')";
statement.executeUpdate(insert);
int workoutID = insertQueryGetId("SELECT workoutID FROM workout");
String insert2 ="INSERT INTO `workout`.`workoutlogs`" + " (`WorkoutID`)"
+ "VALUES('" +workoutID+"')";
statement.executeUpdate(insert2);
connection.close();
}catch(Exception e) {
System.out.println(e);
}
}
public int insertQueryGetId(String query) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/workout","root","");
Statement statement =connection.createStatement();
int workoutID=0;
int result=-1;
try {
workoutID = statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = statement.getGeneratedKeys();
if (rs.next()){
result=rs.getInt(1);
}
rs.close();
statement.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
I've tried using statement for this, but I'm thinking it may have to be prepared statement for it to work. Expecting to store the auto incremented primary key of one table (workouts) into a field within another table (workoutlogs).
It's because you are passing wrong query. Statement.RETURN_GENERATED_KEYS works with Insert queries not with Select queries.
When you insert a row in database, an auto increment value gets generated and is returned but you are passing a Select statement
As Syed Asad Manzoor said, it will work for you but then you need to remove Statement.RETURN_GENERATED_KEYS and statement.executeQuery() has return type of ResultSet so you need to store the result in ResultSet only.
public void insertIntoWorkoutLogs(String field_setNumber, String field_repNumber, String field_weightAmount) {
try{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/workout","root","");
Statement statement =connection.createStatement();
String insert ="INSERT INTO `workout`.`workoutlogs`" + " (`SetNumber`, `RepNumber` , `WeightAmount`)"
+ "VALUES('" +field_setNumber+"','"+field_repNumber+"','"+field_weightAmount+"')";
statement.executeUpdate(insert);
**int workoutID = insertQueryGetId("SELECT workoutID FROM workout");** // Line of Concern 1
String insert2 ="INSERT INTO `workout`.`workoutlogs`" + " (`WorkoutID`)"
+ "VALUES('" +workoutID+"')";
statement.executeUpdate(insert2);
connection.close();
}catch(Exception e) {
System.out.println(e);
}
}
public int insertQueryGetId(String query) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/workout","root","");
Statement statement =connection.createStatement();
int workoutID=0;
int result=-1;
try {
// Line of Concern 2
**workoutID = statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);**
In line (marked as Line of Concern 1 ..
int workoutID = insertQueryGetId("SELECT workoutID FROM workout"); you are passing query as "SELECT...." and at point marked as Line of Concern 2
workoutID = statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS); you are using executeUpdate.. thats why exception is thrown.
Change statement.executeUpdate(query) to statement.executeQuery(query)..
The INSERT statement needs to have flag RETURN_GENERATED_KEYS.
Then getting the ResultSet would deliver for every insert record the generated key(s).
Also use a PreparedStatement for escaping of strings and against SQL injection.
Use try-with-resources to automatically close the several objects, even with exception or early return.
Class.forName("com.mysql.cj.jdbc.Driver");
try (Connection connection = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/workout", "root", "")) {
String insertSql = "INSERT INTO `workout`.`workoutlogs`"
+ " (`SetNumber`, `RepNumber` , `WeightAmount`)"
+ " VALUES(?, ?, ?)";
try (PreparedStatement statement = connection.prepareStatement(insertSql,
Statement.RETURN_GENERATED_KEYS)) {
statement.setString(field_setNumber);
statement.setString(field_repNumber);
statement.setBigDecimal(field_weightAmount);
statement.executeUpdate();
try (ResultSet rs = statement.getGeneratedKey()) {
if (rs.next()) {
int workoutID = rs.getInt(0);
//... second insert here
}
}
}
}
In my Struts2 Java web application users are allowed to query the database. As an example, the user needs to get the employee details whose first name is equal to 'Charles'. Then s/he can select the report columns and criteria (firstname='Charles').
Once the user gives above inputs it need to save the relevant SQL query into the database.
e.g. SQL -> SELECT * FROM employee WHERE firstname='Charles'
Here is what I am trying in my action class.
try {
connection = DriverManager.getConnection(
SelectAction.getDatabase(), SelectAction.getUser(),
SelectAction.getPassword());
if (connection != null) {
System.out.println("Database connection established!");
stmt = connection.createStatement();
String sql = "INSERT INTO reports (report_id, sql) values ('" + reportId + "', '" + sqlQ + "');";
System.out.println("sql--->" + sql);
// Executing query
stmt.executeQuery(sql);
return SUCCESS;
} else {
System.out.println("----Failed to make connection!");
return ERROR;
}
} catch (SQLException e) {
System.out.println("Connection Failed!!");
e.printStackTrace();
return SUCCESS;
}
This is my insert query.
INSERT INTO reports (report_id, sql) values ('mynewreport', 'SELECT * FROM employee WHERE firstname='Charles'');
I am getting following error in my console.
ERROR: syntax error at or near "Charles"
I think here I am using a String so that the problem is with quotes('). I am using postgreSQL as database.
Any suggestions to solve this issue ?
Never use string concatenation of user supplied values to build a SQL statement.
Never use string concatenation of any non-integer values to build a SQL statement.
You will leave yourself open to SQL Injection attacks and/or SQL statement errors.
Hackers will love you for allowing them to steal all your data, and the nefarious ones will corrupt or delete all your data, while laughing maniacally at you on their way to the bank.
Use PreparedStatement and parameter markers.
String sql = "INSERT INTO reports (report_id, sql) values (?, ?)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, reportId);
stmt.setString(2, sqlQ);
stmt.executeUpdate();
}
I am trying to access a database to then insert new data, but the code below gives me this output:
Opened database successfully
java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database ()
The database is created in a different class, I still get this error whether the database has already been created or not.
What would be causing this error?
Statement stmt = null;
Connection c = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:src/test.db");
System.out.println("Opened database successfully");
stmt = c.createStatement();
String sql = "INSERT INTO table_one (id, name) VALUES (Null, 'Hayley');";
stmt.executeUpdate(sql);
System.out.println("Inserted records");
stmt.close();
c.close();
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
System.out.println("Table created sucessfully");
How about not inserting the null value in the id column. It is of no use to insert null value. It might have generated the sql exception. Try INSERT INTO table_one (name) VALUES ('Hayley');.
I would suggest to use PreparedStatement instead of Statement because of the threat of SQL injection.
Sometimes, the particular sql exception can occur if the database name is not given. Have you tried writing the database name like INSERT INTO database_name.table_one (name) VALUES ('Hayley');.
I have a database table with the following layout:
Columns:
_________________________
id | user_name | password
But I can't delete a specified row by using the username.
I am receiving the following error:
MySQLSyntaxErrorException: Unknown column 'vipin' in 'where clause'
vipin is a value within the table.
Can anyone help me?
public void deleteFclty() {
PreparedStatement stmt = null;
ResultSet rs = null;
String username = removeText.getText();
ArrayList<String> values = new ArrayList();
String qry = "SELECT user_name From users ";
try {
stmt = (PreparedStatement) connection.prepareStatement(qry);
rs = stmt.executeQuery();
while (rs.next()) {
values.add(0, rs.getString(("user_name")));
System.out.println(values);
}
} catch (SQLException ex) {
Logger.getLogger(RemoveFaculty.class.getName()).log(Level.SEVERE, null, ex);
}
if (values.contains(username)) {
username = removeText.getText();
Boolean isAdmin = false;
try {
System.out.println(username);
preparedStatement = (PreparedStatement) connection.prepareStatement("DELETE FROM users WHERE user_name=" + username + "");
preparedStatement.executeUpdate();
} catch (SQLException ex) {
Logger.getLogger(RemoveFaculty.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
Util.showErrorMessageDialog(username + " is not found.Please try again.");
}
}
Since you're already using PreparedStatement, use it right and pass the username as parameter instead of just concatenating the Strings:
//no need to use a cast here
preparedStatement = connection.prepareStatement(
//note the usage of ? instead of concatenating Strings
"DELETE FROM users WHERE user_name=?");
//setting the first parameter in the query string to be username
preparedStatement.setString(1, username);
preparedStatement.executeUpdate();
Using this, you won't have any concatenation problems and what's better, your code won't be prone to SQL Injection.
Not directly related to your problem, but it would be better if you move the code to execute INSERT, UPDATE and DELETE statements to a single method.
public void executeUpdate(Connection con, String query, Object ... params)
throws SQLException {
PreparedStatement pstmt = con.prepareStatement(query);
if (params != null) {
int i = 1;
for(Object param : params) {
pstmt.setObject(i++, param);
}
}
pstmt.executeUpdate();
pstmt.close();
}
So your code would be dramatically reduced to:
String deleteSQL = "DELETE FROM users WHERE user_name=?";
executeUpdate(deleteSQL, username);
Note that you can create a new method based on this approach to execute SELECT statements.
Also, don't forget to close your resources. This also can be dramatically reduced using a method like this:
public void closeResource(AutoCloseable res) {
try {
if (res != null) {
res.close();
}
} catch (Exception e) {
//handle this exception...
//basic example, not meant to be used in production!
e.printStacktrace(System.out);
}
}
Note that Connection, Statement (and its children PreparedStatement and CallableStatement) and ResultSet interfaces already extend from AutoCloseable.
You haven't quoted the username you're inserting into the query, so it's being treated as a reference to a field name:
DELETE FROM users WHERE user_name='"+username+"'"
^-- ^--
Note: building queries like this leaves you open to SQL injection attacks. Used prepared statements and placeholders instead.
I think you might need some quotes round the username in the where clause
connection.prepareStatement("DELETE FROM users WHERE user_name='"+username+"'");
You are going to want to quote your Strings
"DELETE FROM users WHERE user_name="+username+"";
Like this:
"DELETE FROM users WHERE user_name='" + username + "'";
What would be better is just using PreparedStatement as it was intended:
"DELETE FROM users WHERE user_name = ?";
And then using:
preparedStatement.setString(1, username);
before calling executeUpdate
The query should look like this
preparedStatement = (PreparedStatement) connection.prepareStatement("DELETE FROM users WHERE user_name='"+username+"'");
Note : Mind the single quotes used for user_name='"+username+"'"
I have a method which does a simple mysql insert, when I tried to rollback the insert action as follow, on an error but it is not rollingback on errors, please assist me,
public void addFamer(FamerDTO famer) throws Exception {
Connection con = JDBCConnectionPool.getInstance().checkOut();
con.setAutoCommit(false);
try {
String generalFamerDataSQL = "INSERT INTO famers(famer_code, name_wt_initials, full_name, gender, "
+ "nic_or_passport_no, sc_possition, phone_home, phone_mobile, phone_office) VALUES(?,?,?,?,?,?,?,?,?)";
PreparedStatement insertFamerPS = con.prepareStatement(generalFamerDataSQL, PreparedStatement.RETURN_GENERATED_KEYS);
insertFamerPS.setString(1, famer.getFamerCode());
insertFamerPS.setString(2, famer.getNameWithInitials());
insertFamerPS.setString(3, famer.getNameInFull());
insertFamerPS.setString(4, famer.getGender());
insertFamerPS.setString(5, famer.getNICorPassportNo());
insertFamerPS.setString(6, famer.getSocietyPosission());
insertFamerPS.setString(7, famer.getHomePhone());
insertFamerPS.setString(8, famer.getMobilePhone());
insertFamerPS.setString(9, famer.getOfficePhone());
insertFamerPS.execute();
String famerRelations = "INSERT INTO org_reg_blk_soc_fmr(org_id, region_id, famer_id, block_id, soc_id) "
+ "VALUES (?,?,?,?,?)";
PreparedStatement famerRelationsPS = con.prepareStatement(famerRelations);
famerRelationsPS.setInt(1, famer.getOrganization().getOrg_id());
famerRelationsPS.setInt(2, famer.getRegion().getRegion_id());
famerRelationsPS.setInt(3, famerID);
famerRelationsPS.setInt(4, famer.getBlock().getBlockId());
famerRelationsPS.setInt(6, famer.getSociety().getSoc_id()); //intentionally made an error here to test, put index as 6 for 5
famerRelationsPS.execute();
con.commit();
} catch (Exception e) {
if (con != null) {
logger.info("Rolling back!");
con.rollback();
}
logger.error(e.getLocalizedMessage());
} finally {
con.setAutoCommit(true);
JDBCConnectionPool.getInstance().checkIn(con);
}
}
once this method is called with the required parameters as there is a error in the second insert statement I expected to rollback the first insert action. but thought the error is shown, a record is added to the data base by the first insert statement.
Just to check - what is the table type you're using? Last time I used MySQL, MyISAM tables didn't support transactions, meaning you have to used another table type e.g. InnoDB.