I'm having a problem with setting up a PreparedStatement to insert a new row into my table. I've tested the query in my SQL editor and it worked succesfully but I can't get this PreparedStatement to work.
String sql = "INSERT INTO table game(gamedate, type, world) values (TIMESTAMP '?', ?, '?');"
runQuery(sql, date, type, world);
...
protected runQuery(String sql, Object... params){
try {
initiateConnection();
PreparedStatement statement = connection.PrepareStatement(sql);
int i = 1;
for (Object p : params){
statement.setObject(i, p);
i++;
}
statement.executeUpdate();
} catch (Exception ex){
} finally {
//close up things
}
}
I added in some println() to test the output and it seemed to all be pretty okay
sql: INSERT INTO game(gamedate, type, world) values(TIMESTAMP '?', ?, '?');
date: 2012-03-13 21:42:14
type: 1
world: test
The error I get is
java.sql.SQLException invalid column index
I'm really quite stumped here. Any idea what's the culprit here?
Two guesses:
you don't need quotes around the question marks. Get rid of those
the TIMESTAMP function might be problematic. Try converting the date to a timestamp before setting it in the prepared statement. (date.getTime() / 1000)
Your SQL statement has only one substitutable placeholder. The ones in single quotes are literal question marks.
Related
i searched here to find solution for my error but no one match my problem , So is there anyone help me to find the error in my code !?
textField_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try{
Object selected = list_1.getSelectedValue();
Connection conn = null;
conn=DriverManager.getConnection("jdbc:mysql://localhost/flyer","root","000");
Statement st= conn.createStatement();
String query = "INSERT INTO flyer_item (discount) SELECT price*? FROM `item` where item_name='?' ";
// PreparedStatement ps = null;
int i = Integer.valueOf((textField_1.getText()));
i=i/100;
java.sql.PreparedStatement ps = conn.prepareStatement(query);
ps.setInt(1,i);
ps.setString(2, selected.toString());
ps.executeUpdate();
st.executeUpdate(query);
} catch (SQLException se){
System.out.println(se.getMessage());
}
} } );
Note : mysql statement it's running successfully in workbench .
thank you
Remove the single quotes around the question mark placeholder
Change this:
where item_name='?'
To this:
where item_name= ?
That should resolve the problem.
With the single quotes, the prepareStatement is seeing the single quotes as enclosing a string literal. The string literal happens to contain a question mark, but it's not seeing that question mark as a bind placeholder.
So the resulting prepared statement only has a single placeholder. Which is why the setString call is encountering an error: there is no second placeholder to supply a value for.
--
EDIT
Also remove this line from the code:
st.executeUpdate(query);
And also remove this line:
Statement st= conn.createStatement();
(The code is creating and using a prepared statement ps.)
remove the quotes from second parameter. within the quotes ? is treated as literal and not as a parameter.
String query = "INSERT INTO flyer_item (discount) SELECT price*? FROM `item` where item_name=?";
type conversion will autonatically handled..
I have a JSON column that I want to create a prepared statement for, but I'm not sure how to go about it since the parameters for the statement are inside a literal string.
For example:
PreparedStatement stmt = myConn.prepareStatement("SELECT JSON_SET(new_friends, '$.?', '[?]') from friend_list where id = ?");
for (int i = 0; i < new_friends.size(); i++) {
String friend = new_friends.get(i);
// not sure what to put here
stmt.set....
stmt.set....
stmt.set(3, i);
}
Anyone have any suggestions?
? placeholders are not used like string interpolation. They replace entire parameters. When the function argument is a string, the entire argument must be the literal string or built with SQL string functions taking parameters as further arguments.
Assuming your syntax is correct for what you want to achieve, consider these:
JSON_SET(new_friends, '$.?', '[?]') -- not valid
JSON_SET(new_friends, ?, ?) -- valid
JSON_SET(new_friends, CONCAT('$.',?), CONCAT('[',?,']')) -- valid
Parameter 1 would be set to the string $.foo for a query in the style of line 2 above, or foo in the style of line 3.
The reason your version isn't valid is exactly the reason you don't/can't use something like WHERE username = '?' but instead would use WHERE username = ? (no quotes around ?).
If you want to add java list objects into a json array like mentioned below:
{"abc":["var1":"val1","var2":"val2","var3":"val3"]}
If there is already a json value in the column then you can use JSON_SET to update value.
String query;
query = "UPADTE tbl1 SET col1 = JSON_SET(col1, '$.abc', CAST(? AS JSON) ) WHERE cdtn = ?";
// if col1 is null then, JSON_SET would be: JSON_SET('{}', '$.abc', CAST(? AS JSON) )
try (Connection conn = DBUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(query)) {
ps.setString(1, jsonArray.toString());
ps.setString(2, cd);
ps.executeUpdate();
}
catch (SQLException e) {
log.error("Error : ", e);
}
private final static String INSERT = "INSERT INTO electric_usage" +
"(objId, useTime, name, usage) " +
"VALUES (?, ?, ?, ?)";
public static boolean insertUsage(int index, Timestamp time, String name, double usage) {
Connection con = null;
try {
con = DBManager.getInstance().getConnection();
PreparedStatement stmt = con.prepareStatement(INSERT);
java.util.Date today = new java.util.Date();
stmt.setInt(1, index);
stmt.setTimestamp(2, time);
stmt.setString(3, name);
stmt.setDouble(4, usage);
stmt.addBatch();
stmt.executeBatch();
stmt.close();
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
DBManager.getInstance().close();
}
return true;
}
make INSERT query like this but this code occur syntax error
other load query is work fine only this INSERT quert occur error
im trying to INSERT query in console it occur same error
my query is wrong?
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 'usage) VALUES (192, '2015-09-10 13:55:57', 'test', 0.0045196452704869055)' at line 1
table is
objId(int length 8 not null)
useTime(timestamp length 0 not null)
name (varchar length 255 not null)
usage (double length 11 not null)
index is a reserved word so you should not use it to name a column. List of reserved words here: http://dev.mysql.com/doc/refman/5.6/en/keywords.html
That's because your column names index/usage are all MySQL Reserve words and so needs to be escaped using backtique like below
INSERT INTO electric_usage (`index`, `time`, `name`, `usage`)
Always avoid using table/column name as reserve word else you will have to suffer likewise. Use proper naming convention like prefix t_ for table names and c_ for column names.
index is reserved word in mysql you can't use mysql reserved words.when you write query in query browser than reserved words shows in blue. so please take care about this.if you write query in java coding directly you can't find these type of issues.
int rs = stmt.executeUpdate("INSERT INTO Leden VALUES (null,"+u+","+p+",'1')");
I'm getting the error
java.sql.SQLException: Unknown column '(the U variable)' in 'field list';
I know for sure it is 100% the "" but i can't seem to find it where it goes wrong
any help is appreciated!
This is my whole method (I want to learn how to do it with a prepared statement)
public static void connectionDB(String u, String p, String f){
{
try {
String username = "/////////";
String password = "///////";
String url = "///////////////";
Connection connection = DriverManager.getConnection(url, username, password);
Statement stmt = connection.createStatement();
int rs = stmt.executeUpdate("INSERT INTO Leden VALUES (null,'"+u+"','"+p+"','1')");
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println("Database connected!");
}
}
It should be like
int rs = stmt.executeUpdate("INSERT INTO Leden VALUES (null,'"+u+"','"+p+"','1')");
Update:-
You can also look into prepared statements because
Prepared statements are much faster when you have to run the same statement multiple times, with different data. Thats because SQL will validate the query only once, whereas if you just use a statement it will validate the query each time.
Assuming fields are A,B,C,D;
A is int and remains are strings
String insertTableSQL = "INSERT INTO Leden"
+ "(A,B,C,D) VALUES"
+ "(?,?,?,?)";
preparedStatement.setInt(1, 11);
preparedStatement.setString(2, "Hello");
preparedStatement.setString(3, "this");
preparedStatement.setString(4, "OP");]
preparedStatement .executeUpdate();
It should be
int rs = stmt.executeUpdate("INSERT INTO Leden VALUES (null,'"+u+"','"+p+"','1')'");
The issue is, that " is used in SQL for objects like columns or tables, whereas ' is used for strings. So in +u+, which seems to not exists in context of your query.
Your query itself should therefore look something like (given, that +u+ and +p+ are strings.
INSERT INTO Leden VALUES (null,'+u+','+p+','1')
If you need to have " inside your columns, it would read like
INSERT INTO Leden VALUES (null,'"+u+"','"+p+"','1')
Also I would recommend to specify the columns you are inserting to so it looks similar to:
INSERT INTO "Leden" ("col1", "col2", "col3", "col4") VALUES (null,'+u+','+p+','1')
This will prevent your query from failing when extending table definition by another column.
Also using prepared statements could be a good idea here, as it helps you preventing from e.g. SQL injections.
I have to develop a small program that inserts some data into an Oracle database. Unfortunately I have some trouble with a SQL Statement and the execution of it. This is the code I am using:
db.execute(
String.format("INSERT INTO tops VALUES (%d, '%s', %d, %f.00, '%s', TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS.FF'))",
item.getID(),
item.getTitle(),
this.elements,
item.getSize(),
item.getEntity(),
timestamp.toString()));
This is the part where the execution should work but I get the following error:
java.sql.SQLException: ORA-00913: Zu viele Werte
Google Translate for exception is:
java.sql.SQLException: ORA-00913: Too many values
You can use prepared statements like this as suggested by Guallaume on the comment;
PreparedStatement pstmt = null;
Connection conn = null;
try{
//if you have a method that creates a connection for you.
conn = getConnection();
pstmt = conn.prepareStatement("INSERT INTO tops(id, title, elements, size, entity, timeStamp) VALUES(?,?,?,?,?,?)");
pstmt.setInt(1,item.getID());
//Assuming that title is a String data type
pstmt.setString(2,item.getTitle());
pstmt.setString(3,this.elements);
pstmt.setDouble(4,item.getSize()); // <--- JDBC will make sure this works
//assuming Entity data type is String
pstmt.setString(5,item.getEntity());
//if your timestamp's string format is
//well formed, you may insert as a string.
pstmt.setString(6,timestamp.toString());
pstmt.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
pstmt.close();
}catch(Exception e){}
try{
conn.close();
}catch(Exception e){}
}
Don't use this syntax
INSERT INTO table VALUES (val1, val2, ...)
Use this one instead
INSERT INTO table (col1, col2, ...) VALUES (val1, val2, ...)
Tables may change. Fields may get added / removed / reordered - in case of which your INSERT statement would break again.
Of course, as others suggest, you should use prepared statements to avoid SQL injection and syntax errors... Imagine, item.getTitle() was any of these
"a', 'b";
"a'); DROP TABLE tops;' ...";
You really should use PreparedStatements, believe us...
In this case, however, the problem is very likely, that your locale uses the comma (,) character for the decimal point..
So 1/4 becomes: 0,25, not 0.25 as the DB would like!
Why is this a problem?
Look at this:
INSERT INTO SOMETABLE VALUES ( 0,25 );
INSERT INTO SOMETABLE VALUES ( 0, 25);
Both are treated as having 2 values, just the first one is not obvious for us, who use the comma as a decimal point... So you have to change the comma to a dot, or change the locale to US.
Correct:
INSERT INTO SOMETABLE VALUES ( 0.25);
You can specify the locale of the string formatting using String.format(Locale l, String format, Object... args) by supplying an appropriate locale.
This format string corrected.
"INSERT INTO tops VALUES (%f, '%s', %f, %.2f, '%s', TO_TIMESTAMP('%s', 'YYYY-MM-DD HH24:MI:SS.FF'))"
Don't use many values for each argument, use exactly one for each one, total six values.