I can't seem to figure out why I'm getting this exception: SQLException: Parameter index out of range (1 > number of parameters, which is 0). My mysql connector version is 5.1.29. Is this possible a problem with this version, or am I not properly setting up the query?
Scratch:
public void actionPerformed(ActionEvent e) {
String query = "INSERT INTO racebikes"
+ "(bikename, country_of_origin, cost) VALUES"
+ "(?,?,?)";
try {
statement.setString(1, (String)winners_combo_box.getSelectedItem());
statement.setString(2, winner_fields[0].getText());
statement.setFloat(3, Float.parseFloat(winner_fields[1].getSelectedText()));
statement.executeUpdate(query);
} catch(SQLException e1) {
e1.printStackTrace();
}
}
You're not assigning a value to statement in that method, and you're using the overload of executeUpdate from Statement... rather than the parameterless one in PreparedStatement.
I suspect you actually want to assign the statement using Connection.prepareStatement:
public void actionPerformed(ActionEvent e) {
String query = "INSERT INTO racebikes"
+ "(bikename, country_of_origin, cost) VALUES"
+ "(?,?,?)";
// TODO: Connection management?
PreparedStatement statement = conn.prepareStatement(query);
try {
statement.setString(1, (String)winners_combo_box.getSelectedItem());
statement.setString(2, winner_fields[0].getText());
statement.setFloat(3, Float.parseFloat(winner_fields[1].getSelectedText()));
statement.executeUpdate();
} catch(SQLException e1) {
e1.printStackTrace();
// TODO: Don't just pretend it worked...
} finally {
statement.close();
}
}
You shouldn't be trying to reuse a statement, basically. Personally I'd try not to reuse a connection, either, using connection pooling to handle reuse of the underlying connection, but that's a different matter.
Related
I'm new in database and sql, and just trying to figure it all out in Java, but I got stuck with some minor problem, I'm trying to remove one record in db, with id that is given as method parameter, like this, but it's not working
#Override
public void removeCustomer(int number) {
Statement statement = null;
try {
statement = connection.createStatement();
statement.executeUpdate("DELETE FROM Customers WHERE id='number'");
} catch (SQLException e) {
e.printStackTrace();
} finally {
try{
if(statement != null) statement.close();
} catch (SQLException e ) {
e.printStackTrace();
}
}
}
It does work, when I write in SQL query " ... WHERE id='2'";
But I want to be able to pass the number from method parameter.
Anyone could help?
You can use PreparedStatement like so :
try(PreparedStatement stm = connection.createStatement("DELETE FROM Customers WHERE id=?")){
stm.setInt(1, number);
stm.executeUpdate();
}
//.. catch and finally
Note
It does work, when I write in SQL query " ... WHERE id='2'";
If in case your id is a varchar you can pass a string to the statement by using setString instead of setInt, but I don't suggest to use string for id
I am working in swing based project and use prepared statement but it give exception like out of range and when i using parameters and do not put '?' but simply ? then show exception like"
jdbc syntax error check the manual near '?,?' at line one " i am so confused what is happening.Check my code what is wrong?
private void AddActionPerformed(java.awt.event.ActionEvent evt) {
if (((JTextField) chose.getDateEditor().getUiComponent()).getText() == null) {
String sql = "INSERT INTO expance1 ( Breakfast,Date) VALUES (?,?)";
} else {
String sql = "INSERT INTO expance1 ( Breakfast,Date) VALUES (?,?)";
try {
pst = conn.prepareStatement(sql);
pst.setString(1, breakfast.getText());
pst.setString(2, ((JTextField) chose.getDateEditor().getUiComponent()).getText());
pst.executeUpdate(sql);
JOptionPane.showMessageDialog(null, "insert sucessfully");
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
} finally {
try {
rs.close();
pst.close();
} catch (Exception e) {
}
}
}
}
Replace
pst.executeUpdate(sql);
by
pst.executeUpdate();
The SQL query has already been passed to the statement when preparing it. You must not pass it a second time. Passing it executes the literal SQL query, not the prepared one.
How do I insert a list of values into a column in a MySQL table.
Here is my project:
public void settingAmount(List<String>lst)throws Exception{
// Accessing driver from jar files
Class.forName("com.mysql.jdbc.Driver");
// here we create a variable for the connection called con
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/ozon","root","root");
// here we create our query
Statement stmt = (Statement) con.createStatement();
//performing insert operation :)
lst.toArray(ss);
for(String ins:ss){
double d=Double.parseDouble(ins);
String insert = "INSERT INTO storage_other(total) VALUES ("+ins+");";
//String insert = "INSERT INTO storage_other(amount) VALUES ("+ls+");";
// Here we are going to Execute the query
stmt.executeUpdate(insert);
System.out.print("Done Seccesfully :)");
}
}
What you want to do is use batches. Batches allow you to send a list of statements to be done at the same time.
Here is an example
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement("INSERT INTO storage_other(total) VALUES (?)");
for (String ins:ss){
ps.setObject(1, d);
ps.addBatch();
}
ps.executeBatch();
connection.commit();
This will be significantly faster than individual inserts on any table with indexes.
This is a method I used in order to insert some data in an Oracle SQL database.
private boolean submit(Connection con, String query){
try {
PreparedStatement preStatement;
preStatement = con.prepareStatement(query);
preStatement.executeQuery();
preStatement.close();
return true;
}catch (Exception e) {
System.out.println("Exception cought, updating log.");
return false;
}
}
You can prepare your insert statement and call this function to perform the action. Call it using your connection object and the query. It shall return true on completion false in case something goes wrong. If you want to log any errors, use e.getMessage() to get the error message as a String in the exception block.
As mentioned in the comments, try to use the PreparedStatement object to avoid SQL Injection attacks and also try to trim any ' you might have in your data.
Here's how I'd recommend you do it. A few thoughts:
Give the Connection to the object. That method should do one thing: the INSERT.
Should be transactional.
Should clean up resources when done.
Tell users to provide a List of Doubles if that is what the amounts are. Don't parse; let clients do that.
Here is complete code:
public class Inserter {
private static final String INSERT_SQL = "INSERT INTO storage_other(total) VALUES(?))";
private Connection connection;
public Inserter(Connection connection) {
this.connection = connection;
}
public int settingAmount(List<Double> amounts)throws SQLException {
int numAmountsInserted = 0;
PreparedStatement ps = null;
this.connection.setAutoCommit(false);
try {
ps = this.connection.prepareStatement(INSERT_SQL);
for(Double amount : amounts) {
ps.setDouble(1, amount);
numAmountsInserted += ps.executeUpdate();
}
this.connection.commit();
} catch (SQLException e) {
DatabaseUtils.rollback(this.connection);
throw e;
} finally {
DatabaseUtils.close(ps);
this.connection.setAutoCommit(true);
}
return numAmountsInserted;
}
}
I know it is basics and probably really simple, but I'm struggling with the following situation where i want to query the database for a specific int(id in my case), but somehow i can't acces the returned data from the data set.
I have tested the query in db managment system and it works. I get no errors/ stacks but the result of my method is always -1.(Which means it fails :( because no int has been parsed)
code:
public int UserFactoryEngine(String n, String p){
// query for user data, validate and return
Connection conn = null;
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
System.out.println("Failure intialization of the driver! ");
e.printStackTrace();
}
String connectionUrl = "jdbc:sqlserver://localhost:1433;" + "databaseName=BugsSurveillance;user=sa;password=1234;integratedSecurity=true;";
try {
conn = DriverManager.getConnection(connectionUrl);
} catch (SQLException e) {
System.out.println("Failure intialization of the connection! ");
e.printStackTrace();
}
System.out.println("Connected... ");
String sqlquery;
PreparedStatement preparedStatement;
ResultSet rs;
try {
preparedStatement = conn.prepareStatement("SELECT id FROM Users WHERE name = ? AND pass = ? ",
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
preparedStatement.setString(1, n);
preparedStatement.setString(2, p);
rs = preparedStatement.executeQuery();
while (rs.next()){
System.out.println(rs.getInt(1));
}
} catch (SQLException e) {
System.out.println("Prepared statement failure!");
e.printStackTrace();
}
return -1;
}
You're not getting any output to the console from the
while (rs.next()){
System.out.println(rs.getInt(1));
}
because there are no results. Initially the ResultSet is pointed before the first row. When next() is called, it increments to the next row, and returns true only if the new current row is valid, which it must not be in this case.
Since you say the row exists, try replacing your lines
preparedStatement.setString(1, n);
preparedStatement.setString(2, p);
with hard coded values, for testing. So, if your username is admin, and your password is 1234.
preparedStatement.setString(1, "admin");
preparedStatement.setString(2, "1234");
Another test you could try is to
SELECT * FROM users
and see if you get any results that way.
Considering this is a login factory(what i'm trying to implement) i have been using a JPasswordField, which it seems needs a bit more atention when it comes to the getPassword() method. So because of that I wasen't able to succesfully find some matching string in database.
Fix: used JTextfield with hidden characters.
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.