I have the following scenario :
Map<String, HashSet<String>> B = new HashMap<String, HashSet<String>>();
if(!B.containsKey(row5.issue)){
B.put(row5.issue,new HashSet<String>());
}
B.get(row5.issue).add(row5.name);
globalMap.put("BMap", B);
Now, I have the following scripts in another Subjob:
"select * from Table where name in ('" + BMap.values() + "');"
The bold portion has problems, anyone can advise? Thanks very much.
Iterate through your BMap and build a String based on it's values to query the database with. I am presuming your HashSet<String> holds the names in your HashMap<String, HashSet<String>>.
String sql_statement = "";
for(HashSet<String> names : BMap.values()){
for(String name : names){
sql_statement += "'" + name + "',";
}
}
sql_statement = sql_statement.substring(0, sql_statement.length-1); // to remove the comma at the end
And the select statement will look like this:
"select * from Table where name in (" + sql_statement +");"
I haven't tested this but it should give you the general idea on how to fix this problem.
Related
I'm searching for a word (variable) that occurs in multiple columns of a table. The search has to return the name of the columns in which the word in found.
I could use a foreach loop to go through each column seperately and know the presence of the word in that particular column when the returned cursor isn't null.
The problem is on how to use two different variables (one for column name and one for the word) in SQL query or rawQuery.
My code is as follows:
String[] columnsList = {"col1","col2","col3"};
String[] wordsList = {"fireman","camper","builder"};
for(String i : wordsList){
for(String j : columnsList){
Cursor wordQuery = myDatabaseHandle.rawQuery("Select * from myTableOne WHERE " + j + " = ?",new String[]{i});
if(!(wordQuery==null)){
Toast.makeText(this,j+"is success",Toast.LENGTH_SHORT).show();
}
}
}
But i'm unable to get the answer. I used a seperate string as:
String queryString = "Select * from myTableOne WHERE " + j ;
and in the query,
Cursor WordQuery = myDatabaseHandle.rawQuery(queryString+" = ?",new String[]{i});
But, it's just toasting the names of all columns.
Your error is here:
if(!(wordQuery==null)){
The cursor is never null.
It can contain 0 records, though.
You can check its length by using wordQuery.getCount()
Something like:
if((wordQuery.getCount() > 0)){
I'm trying to insert a JSONObject that contains a couple of JSONArrays in it inside a MySQL database that I have.
This is what I'm currently trying to do:
JSONObject fiveMin = new JSONObject();
JSONArray data = new JSONArray();
data.add(45);
fiveMin.put("data", data);
String query = "UPDATE frame_data.all_frame_data"
+ "SET 5_min_data = " + fiveMin
+ " WHERE stock_id = 1";
stmt.executeUpdate(query);
However, it's giving me a null pointer exception.
Anyone know how to fix this? I've been stuck on this for days
your Query is not correct you need a space after frame_data.all_frame_data because this now look like frame_data.all_frame_dataSET 5_min_data, change your Query to be like this :
String query = "UPDATE frame_data.all_frame_data SET 5_min_data = " + fiveMin
+ " WHERE stock_id = 1";
Second i don't think that there are a type JSONObject in MySql so i think you are using a varchar or a text to store your data, so fiveMin should convert to a String and not set like you do for example :
fiveMin.toString();
You query should look like this :
String query = "UPDATE frame_data.all_frame_data SET 5_min_data = '" + fiveMin.toString()
+ "' WHERE stock_id = 1";
I suggest to use PreparedStatement you can learn more here : PreparedStatement
Thank you.
Question
With MySQL and using a JDBC template, is there a way to build parameters from Java Lists so that the SQL request matches a couple of values with couples of values in a given set?
Details
The values should match only if the couple of values is present in the list.
It should not match if one is present in a couple of values and the other in another couple further into the list of couples.
That is to say, given that JDBC parametrized query:
SELECT *
FROM TABLE_1
WHERE (COL_1, COL_2) IN (:valuesSet)
Caution: valuesSet is a set of couples
And that Java code:
public void daoMethod(List<MyObject> values1, List<MyObject> values2) {
String query = "";
query = "SELECT *\n" +
"FROM TABLE_1\n" +
"WHERE (COL_1, COL_2) IN (:valuesSet)";
MapSqlParameterSource parameters = new MapSqlParameterSource();
// Build valuesSet here
parameters.addValue("valuesSet", valuesSet);
namedParameterJdbcTemplate.query(query, parameters);
}
Is there an elegant way to build a JDBC template without having to "manually" create the string?
The inserted :valuesSet should be something like:
"(values1.get(0), values2.get(0)), (values1.get(1), values2.get(1)), ..."
But how should I build that string?
Current Track
Currently, my first draft solution is to build the string by Java code like this:
List<String> valuesSet = new ArrayList<String>();
for (int i = 0; i < values1.size(); i++) {
String value1 = StringEscapeUtils.escapeSql(values1.get(i).toString());
String value2 = StringEscapeUtils.escapeSql(values2.get(i).toString());
valuesSet.add("('" + value1 + "','" + value2 + "')");
}
But it keeps escaping the result list to make it a String and adds ' around it. Therefore, it's not working.
TL;DR
Input:
List<Object> objects
Output:
SELECT *
FROM TABLE_1
WHERE (COL_1, COL_2) IN (
('object_1_val1', 'object_1_val2'),
('object_2_val1', 'object_2_val2'),
('object_3_val1', 'object_3_val2'),
('object_4_val1', 'object_4_val2'),
...
)
Mean:
NamedParameterJdbcTemplate
Use every value separately.
List<String> valuesSet = new ArrayList<>();
StringBuilder sqlIn = new SqlBuilder();
for (int i = 0; i < values1.size(); i++) {
sqlIn.append("(?, ?),");
valuesSet.add(values1.get(i).toString());
valuesSet.add(values2.get(i).toString());
}
I found out a workaround using CONCAT():
SELECT *
FROM TABLE_1
WHERE CONCAT(COL_1, ',', COL_2) IN (:valuesSet);
That way, valuesSet can be a simple list of strings and is passed as the following:
List<String> valuesSet = new ArrayList<String>();
for (int i = 0; i < values1.size(); i++) {
String value1 = StringEscapeUtils.escapeSql(values1.get(i).toString());
String value2 = StringEscapeUtils.escapeSql(values2.get(i).toString());
valuesSet.add(value1 + "," + value2;
}
parameters.addValue("valuesSet", valuesSet);
Then, the executed query is something like:
SELECT *
FROM TABLE_1
WHERE CONCAT(COL_1, ',', COL_2) IN (
'object_1_val1,object_2_val1',
'object_1_val2,object_2_val2',
'object_1_val3,object_2_val3',
'object_1_val4,object_2_val4',
...
);
I'm trying to make a query with selected fields for final user from view (JSP) to controller, but I don't know how.
For example, I have this parameters from view (JSP)
IDUSER,>,2,OR,USERNAME,=,'KURT'
So, I'll want to have something like this,
SELECT IDUSER, USERNAME FROM TABLE_NAME WHERE IDUSER > 2 OR USERNAME = 'KURT'
but I have next result
SELECT null FROM TABLE_NAME WHERE IDUSER > 2 OR USERNAME = 'KURT'
I'm parsing string with StringTokenizer class, where query is: String query = request.getParameter("data"); and data is IDUSER,>,2,OR,USERNAME,=,'KURT'.
StringTokenizer field = new StringTokenizer(query, ",");
nFields = field.countTokens();
System.out.println("nFields: " + nFields);
String[] fields = new String[nFields];
for(int i = 0; i < fields.length; i++) {
while(field.hasMoreTokens()) {
fields[i] = field.nextToken();
}
System.out.println("fields[i]: " + fields[i]);
myQuery = "SELECT " + fields[i] + " FROM "+tableName+ " WHERE ";
System.out.println("myQuery 1: " + myQuery);
}
StringTokenizer token= new StringTokenizer(query, "|,");
while(token.hasMoreTokens()) {
myQuery = myQuery + token.nextToken() + " ";
}
System.out.println("QUERY RESOLVED: " + myQuery);
PLEASE HELP ME
Here is the solution after minor tweak in your query (redefined the separators)
public static void main(String[] args) {
// Redefine the separators as single , separators is difficult to process
//You would need to define possible operators like this (#OR# , #AND# ) ,surrounded by special characters to identify.
String query ="IDUSER_>_2#OR#USERNAME_=_'KURT'";
String tableName="TESTTABLE";
String operator=null;
//you can choose operator conditionally
if(query.contains("#OR#")) operator="#OR#";
// if(query.contains("#AND#")) operator="#AND#";
//Used split instead of Tokenizer.
String cols[]= query.split(operator);
String myQuery = "SELECT ";
String select="";
for(String col:cols){
if(!select.isEmpty()){
select+=" , ";
}
// Only the first element is retrieved (for select)
select+=col.split("_")[0];
}
myQuery+=select+" FROM "+tableName+ " WHERE ";
// Removes all special charecters (like, # and _ with white space)
String subQuery = query.replaceAll("#", " ");
subQuery=subQuery.replaceAll("_", "");
myQuery+=subQuery;
System.out.println("QUERY RESOLVED: " + myQuery);
}
Note : ',' is replaced with '_' and operators are surrounded by '#'
Cheers!!
I think the problem is this line in your while loop:
myQuery = "SELECT " + fields[i] + " FROM "+tableName+ " WHERE ";
This will keep changing the value of myQuery as the while loop executes.
Maybe you need to replace this with:
myQuery = "SELECT " + fields[0] + " FROM "+tableName+ " WHERE ";
break;
I am assuming your selection criteria is the first field in the parameter from your view.
Do not see where does IDPERFIL come from. Also, I don't like this:
while(field.hasMoreTokens()) {
fields[i] = field.nextToken();
}
That will iterate tokenizer to the end, and stop at last element. I am sure you don't want this. Fix that, tell where IDPERFIL come from, and then, maybe, you'll understand answer by yourself. Otherwise, I'll try to help further.
I am trying to use a MapSqlParameterSource to create a query using a Like clause.
The code is something like this. The function containing it receives nameParam:
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE :pname ";
String finalName= "'%" +nameParam.toLowerCase().trim() + "%'";
MapSqlParameterSource namedParams= new MapSqlParameterSource();
namedParams.addValue("pname", finalName);
int count= this.namedParamJdbcTemplate.queryForInt(namecount, namedParams);
This does not work correctly, giving me somewhere between 0-10 results when I should be receiving thousands. I essentially want the final query to look like:
SELECT count(*) FROM People WHERE LOWER(NAME) LIKE '%name%'
but this is evidently not happening. Any help would be appreciated.
Edit:
I have also tried putting the '%'s in the SQL, like
String finalName= nameParam.toLowerCase().trim();
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE '%:pname%' "
;
but this does not work either.
You don't want the quotes around your finalName string. with the named parameters you don't need to specify them. This should work:
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE :pname ";
String finalName= "%" + nameParam.toLowerCase().trim() + "%";
MapSqlParameterSource namedParams= new MapSqlParameterSource();
namedParams.addValue("pname", finalName);
int count= this.namedParamJdbcTemplate.queryForInt(namecount, namedParams);
This solution worked for me. I put the "%" on the Object[] parameters list:
String sqlCommand = "SELECT customer_id, customer_identifier_short, CONCAT(RTRIM(customer_identifier_a),' ', RTRIM(customer_identifier_b)) customerFullName "
+ " FROM Customer "
+ " WHERE customer_identifier_short LIKE ? OR customer_identifier_a LIKE ? "
+ " LIMIT 10";
List<Customer> customers = getJdbcTemplate().query(sqlCommand, new Object[] { query + "%", query + "%"}, new RowMapper<Customer>() {
public Customer mapRow(ResultSet rs, int i) throws SQLException {
Customer customer = new Customer();
customer.setCustomerFullName(rs.getString("customerFullName"));
customer.setCustomerIdentifier(rs.getString("customer_identifier_short"));
customer.setCustomerID(rs.getInt("customer_id"));
return customer;
}
});
return customers;
Have you tried placing the % wild cards in your sql string (not the bind variable value itself):
String finalName= nameParam.toLowerCase().trim();
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE '%:finalName%'";
We can use simple JdbcTemplate instead of NamedParamJdbcTemplate
String namecount = "SELECT count(*) FROM People WHERE LOWER(NAME) LIKE ? ";
String finalName= "%" +nameParam.toLowerCase().trim() + "%"; //Notes: no quote
getJdbcTemplate().queryForInt(namecount, new Object[] {finalName});
Hope it helpful for someone using JdbcTemplate