I'm using this:
PreparedStatement preStatement = conn.prepareStatement("SELECT * FROM SomeTable WHERE attributeId = ? AND substring_index(substring_index(rowIdCombo,',',2),',',-1) = ?");
preStatement.setString(1, anAttributeID.toString());
preStatement.setString(2, locationID.toString());
Searching using the same query works fine on the MySQL terminal. It's only when using PreparedStatement in Java that it doesn't.
rowIdCombo is basically a string of numbers with comma separated values. Something like this: 23,56,64,3.
The result set returned is empty. How do I get this query to work?
Based on the output of
System.out.println(preStatement);
which was:
com.mysql.jdbc.PreparedStatement#223d2c72: SELECT * FROM mydb.SomeTable WHERE attributeId = '6' AND substring_index(substring_index(rowIdCombo,',',2),',',-1) = '1'
and as per your comment, that replacing = '1' with = 1 have solved the issue, to prevent the single quotes wrapping, set the value in the PreparedStatement as integer, use this:
preStatement.setInt(2, Integer.parseInt(locationID.toString()));
Related
I am trying to generate sql query based on user input. There are 4 search fields on the UI:
FIRST_NAME, LAST_NAME, SUBJECT, MARKS
Based on user input I am planning to generate SQL query. Input can be of any combination.
eg: select * from TABLE where FIRST_NAME="some_value";
This query needs to be generated when FIRST_NAME is given and other fields are null
select * from TABLE where FIRST_NAME="some_value" and LAST_NAME="some_value";
This query needs to be generated when FIRST_NAME and LAST_NAME are given and other fields are null
Since there are 4 input fields, number of possible queries that can be generated are 24 (factorial of 4).
One idea is to write if condition for all 24 cases.
Java pseudo code:
String QUERY = "select * from TABLE where ";
if (FIRST_NAME!=null) {
QUERY = QUERY + "FIRST_NAME='use_input_value';"
}
if (LAST_NAME!=null) {
QUERY = QUERY + "LAST_NAME='use_input_value';"
}
if (SUBJECT!=null) {
QUERY = QUERY + "SUBJECT='use_input_value';"
}
if (MARKS!=null) {
QUERY = QUERY + "MARKS='use_input_value';"
}
I am not able to figure out how to generate SQL queries with AND coditions for multiple Input values.
I have been through concepts on dynamically generate sql query but couldn't process further.
Can someone help me on this.
FYI: I have been through How to dynamically generate SQL query based on user's selections?, still not able to generate query string based on user input.
Let's think about what would happen if you just ran the code you wrote and both FIRST_NAME and LAST_NAME are provided. You'll wind up with this:
select * from TABLE where FIRST_NAME='use_input_value';LAST_NAME='use_input_value';
There are two problems here:
The query is syntactically incorrect.
It contains the literals 'use_input_value' instead of the values you want.
To fix the first problem, let's first add and to the start of each expression, and remove the semicolons, something like this:
String QUERY = "select * from TABLE where";
if (FIRST_NAME!=null) {
QUERY = QUERY + " and FIRST_NAME='use_input_value'";
}
Notice the space before the and. We can also remove the space after where.
Now the query with both FIRST_NAME and LAST_NAME will look like this:
select * from TABLE where and FIRST_NAME='use_input_value' and LAST_NAME='use_input_value'
Better but now there's an extra and. We can fix that by adding a dummy always-true condition at the start of the query:
String QUERY = "select * from TABLE where 1=1";
Then we append a semicolon after all the conditions have been evaluated, and we have a valid query:
select * from TABLE where 1=1 and FIRST_NAME='use_input_value' and LAST_NAME='use_input_value';
(It may not be necessary to append the semicolon. Most databases don't require semicolons at the end of a single query like this.)
On to the string literals. You should add a placeholder instead, and simultaneously add the value you want to use to a List.
String QUERY = "select * from TABLE where";
List<String> args = new ArrayList<>();
if (FIRST_NAME!=null) {
QUERY = QUERY + " and FIRST_NAME=?";
args.add(FIRST_NAME);
}
After you've handled all the conditions you'll have a string with N '?' placeholders and a List with N values. At that point just prepare a query from the SQL string and add the placeholders.
PreparedStatement statement = conn.prepareStatement(QUERY);
for (int i = 0; i < args.size(); i++) {
statement.setString(i + 1, args[i]);
}
For some reason columns and parameters are indexed starting at 1 in the JDBC API, so we have to add 1 to i to produce the parameter index.
Then execute the PreparedStatement.
I use prepared statements to read/write data in my DB (SQLite). In my table INVENTORY, there are records which have null value in the column paleta (the column is defined as VARCHAR in the table). I want to select these records and I tried:
sq = "SELECT * FROM INVENTORY WHERE paleta = ? AND product = ? AND lot = ?";
//...
stm = c.prepareStatement(sq);
stm.setNull(1, java.sql.Types.VARCHAR);
stm.setString(2, "theIdOftheProduct");
stm.setString(3, "theLotOftheProduct");
ResultSet rs = stm.executeQuery();
The above query doesn't return anything.. I removed the paleta = ? and I get the records I want.. How can I define the query like SELECT * FROM INVENTORY WHERE paleta is null etc.. using the query parameters?
What you are trying to do is equivalent to writing SELECT * FROM INVENTORY WHERE paleta = NULL ..., which doesn't work.
Since you are essentially searching for rows having a constant value in the paleta column (which happens to be NULL), you can eliminate the first query parameter and explicitly check for null:
sq = "SELECT * FROM INVENTORY WHERE paleta IS NULL AND product = ? AND lot = ?";
stm = c.prepareStatement(sq);
stm.setString(1, "theIdOftheProduct");
stm.setString(2, "theLotOftheProduct");
I found my answer in https://stackoverflow.com/a/4215618/1052284
You'll have to decide upon an unused value. I simply kept it at '' since I don't have empty values.
sq = "SELECT * FROM INVENTORY WHERE IFNULL(paleta, '') = ? AND product = ? AND lot = ?";
//...
stm = c.prepareStatement(sq);
stm.setString(1, ""); // '' for NULL, otherwise a specific value
stm.setString(2, "theIdOftheProduct");
stm.setString(3, "theLotOftheProduct");
But beware if you many queries, it's VERY slow. I clock in at about 4000 times slower, on average, than queries without IFNULL. ~50ms instead of microseconds.
How to update a field in my database from a JTextField using java?
My field in the data base: total
My field in java: add_quantity
I need to add the quantity to the total, using sql.
total = total + add_quantity
I tried this:
String value1 = jTextField5.getText();
PreparedStatement pst = cn.prepareStatement("UPDATE Capitales_totales SET capital_total = $capital_total + '"+value1+"';
What is the correct syntax for doing that?
Your question isn't very clear, datatype of the capital_total isn't provided. So, we'll assume that it's integer or numeric datatype.
MySQL syntax to add a value to the value that's already stored in a column, is something like this:
UPDATE mytable
SET mycol = mycol + 20
WHERE id = 1
If mycol contains a NULL value, then a NULL will be assigned. (An unknown value
plus 20 results in an unknown value.) If you want to handle a NULL value as if it were zero...
UPDATE mytable
SET mycol = IFNULL(mycol,0) + 20
WHERE id = 1
As far as how you do that in Java prepared statement, use a bind placeholder in place of the value in the SQL text, and then provide a value for the bind placeholder with the setString method.
String sql = "UPDATE mytable
SET mycol = IFNULL(mycol,0) + ?
WHERE id = 1";
PreparedStmt pst = cn.prepareStatement(sql);
pst.setString(1, value1);
Try using binds, e.g.
PreparedStatement pst = cn.prepareStatement("UPDATE Capitales_totales SET capital_total = capital_total + ?");
pst.setInt(1, Integer.parseInt(value1));
Note: Integer.parseInt() may throw RuntimeExpection
sample code snippet for the use-case:
PreparedStatement pst = cn.prepareStatement("Update Capitales_totales set capital_total =capital_total+?");
pst.setString(1, Integer.parseInt("int_string"));
OR
pst.setInt(1, 1001); //sample int 1001
int selectie = toernooienUitvoer.getSelectedRow();
int selectiec = toernooienUitvoer.getSelectedColumn();
String primarykey = (String) toernooienUitvoer.getValueAt(selectie, 0).toString();
String waarde = toernooienUitvoer.getValueAt(selectie, selectiec).toString();
String columnaam = toernooienUitvoer.getModel().getColumnName(selectiec).toString();
String input = JOptionPane.showInputDialog("wijzig geselecteerde data", waarde);
toernooienUitvoer.setValueAt(input, selectie, selectiec);
PreparedStatement stat = con.prepareStatement("UPDATE fullhouse.toernooi SET ? = ? WHERE toernooi.T_code = ?");
stat.setString(1, columnaam);
stat.setString(2, input);
stat.setString(3, primarykey);
Guys, i know the query is correct, if i input the values. my guess my mistake is somewhere in the preparedstatement
i am getting a MySQLSyntaxErrorException:
As mentioned in other answer, the placeholder ? can only be used for values, not for table and column names. Since you are not reusing the PreparedStatement this is quite simple.
Change from
PreparedStatement stat = con.prepareStatement("UPDATE fullhouse.toernooi SET ? = ? WHERE toernooi.T_code = ?")
to
PreparedStatement stat = con.prepareStatement("UPDATE fullhouse.toernooi SET " + columnName + " = ? WHERE toernooi.T_code = ?")
And adjust the index parameter in the setString calls.
I don't think you can use place holder for dynamically passing the column name,your query should be:
"UPDATE fullhouse.toernooi SET colname = ? WHERE toernooi.T_code = ?"
When you use bind variables, it means the statement is precompiled and on the next executions, it will be faster. You are trying to make the name of the column to be a bind variable, which is not possible.
because you obviously need to update several different columns, in order to achieve some speed, you should declare several prepared statements, one for each column. Keep them in a HashMap<String, PreparedStatement>
The column name of a prepared statement cannot be dynamic because, depending on the column name, the query plan will be wildly different (e.g. sometimes table scan will be the fastest, sometimes using an index, sometimes something even more esoteric).
If SQL can't rely on a certain plan being the fastest, it needs to come up with a new one every time - which means there's no point in making a prepared statement which is why you can't do it.
I have an SQL query that i am going to run using a PreparedStatement, and it is
UPDATE tbl_HitsCounter SET count = ? WHERE keyid = (SELECT id FROM tbl_HitsMaster WHERE sitename = '?')
Now when i set the 2nd paramater, which is a string value, i am getting a strange SQLException.
preparedStatement.setInt(1, 99);
preparedStatement.setString(2, masterKey);
As the setString() method is executed, i am getting an SQLException
The column position '2' is out of range. The number of columns for this ResultSet is '1'.
I have no idea what this is about, i havent even executed the executeUpdate() method.
There is only one placeholder in your SQL but you are trying to assign a value for the second. Your problem is that you have quoted the second placeholder, your SQL should look more like this:
UPDATE tbl_HitsCounter
SET count = ?
WHERE keyid = (
SELECT id
FROM tbl_HitsMaster
WHERE sitename = ?
)
Note the lack of quotes in sitename = ?. This is a placeholder: ?. This is an SQL question mark string literal: '?'.