Multiple parameters to SQL JdbcTemplate - java

I have query like
`Select * from Table1 where xyz in (List of String to be Supplied).
In my java code. I have a dao object in which I am calling this sql using jdbc template.
The method takes in a list of String and that needs to be supplied to this SQl. I have my row-mapper.
How to write the SQl and how to pass the list of variables?
My SQL will run on a Teradata Db.

Use a NamedParameterJdbcTemplate which, as the doc says:
It also allows for expanding a List of values to the appropriate number of placeholders.
So you just need
String sql = "select * from Table1 where xyz in :list";
// or String sql = "select * from Table1 where xyz in (:list)";
// I can't remember which one is right
Map parameters = new HashMap<String, Object>();
parameters.put("list", theListOfXyz);
List<Foo> result = template.query(sql, parameters, rowMapper);

Related

Create table as select with parameter using jdbcTemplate

I want to use jdbcTemplate to create table based on another table under condition. I have postgres database. When I execute this and pass parameter:
String SQL = "create table test as (select * from users where countryId =?)";
jdbcTemplate.update(SQL, new Object[] {3})
I receive table test with all columns from users table but with no rows.
However, when I execute this:
String SQL = "create table test as (select * from users where countryId =3)";
jdbcTemplate.update(SQL)
I receive test table with rows where countryId = 3, so that is what I was expecting to receive in the first solution.
Your passing of the bind variable is not correct, but it does not play any role.
You simple can not use a bind variable in a data definition statement as you immediately see in the triggered error
Caught: org.springframework.jdbc.UncategorizedSQLException:
PreparedStatementCallback; uncategorized SQLException for SQL
[create table test as (select * from users where countryId =?)];
SQL state [72000]; error code [1027];
ORA-01027: bind variables not allowed for data definition operations
So you have two options, either concatenate the statement (which is not recommended due to the danger of SQL injection)
or split the statement in two parts:
// create empty table
sql = "create table test as (select * from users where 1 = 0)";
jdbcTemplate.update(sql)
// insert data
sql = "insert into test(countryId, name) select countryId, name from users where countryId =?";
updCnt = jdbcTemplate.update(sql, new SqlParameterValue(Types.INTEGER,3));
Note that in the insert statement you can see the correct way of passing an interger value of 3 as a bind variable.
You can follow below approach as well:-
jdbcTemplate.execute("CREATE TABLE IF NOT EXISTS employee_tmp (id INT NOT NULL)");
List<Object[]> employeeIds = new ArrayList<>();
for (Integer id : ids) {
employeeIds.add(new Object[] { id });
}
jdbcTemplate.batchUpdate("INSERT INTO employee_tmp VALUES(?)", employeeIds);
Here you may query with 2 operations to avoid SQL injection.
You are using method update from jdbcTemplate in a wrong way.
Try with this:
String SQL = "create table test as (select * from users where countryId = ?)";
jdbcTemplate.update(SQL, 3);

How to generate sql from template and param placeholder with JOOQ?

I get the sql template like this with jOOQ 3.11.11.
DSLContext context = new DefaultDSLContext(conf);
Query query = context.select().from("table1").where(DSL.field("report_date").eq(DSL.param("bizdate")));
String sqlTemp = context.renderNamedParams(query);
I store the plain sql template.
select * from table1 where report_date = :bizdate
The param 'bizdate' is decided by realtime query.
So. How to generate the real sql
select * from table1 where report_date = '20190801'
with the stored sql template string and the realtime input date '20190801'.
You can use this:
context.resultQuery(sqlTemp, DSL.param("bizdate", "20190801")).fetch();
See DSLContext.resultQuery(String, QueryPart...)

Pass list of values on query parameter

String hql = "select * from myTable where isActive IN (:isActive)";
Query query = session.createQuery(hql);
query.setString("school","");
query.setString("isActive", "Y");//working
query.setString("isActive", "N");//working
query.setString("isActive", "Y","N"); // not working
query.setString("isActive", "'Y','N'"); // not working
return query.list();
I have no idea if the code below should work, I was wondering if i can pass list of values to my search string parameter so there's no need for me to create to queries ; one for select all data regardless of status and another to select only active data.
Use Query.setParameterList() to pass in a List as a parameter:
String hql = "select * from myTable where isActive IN (:isActive)";
Query query = session.createQuery(hql);
List<String> isActiveList = new ArrayList<>();
isActiveList.add("Y");
isActiveList.add("N");
query.setParameterList("isActive", isActiveList);
return query.list();

How to send List of dates as part of sql query using SpringTemplate + JDBCTemplate

Well, I have a query like this :
SELECT * FROM table WHERE someDate IN (date1, date2, date3);
I am trying to construct this using ST (SpringTemplate) and am using JDBCTemplate to make the query.
If I have to pass only one date, I can use :
stringTemplateInstance.add("someColKey",dateInstance);
But how can I send a list of dates so that the IN clause gets it?.
Right now, I am using StringUtils.collectionToCommaDelimitedString(dateListForQuery); to the query ( which I don't like).
Ditch both the StringTemplate as well as the JdbcTemplate and switch to the NamedParameterJdbcTemplate.
String query = "select * from table where someDate in (:dates)";
Map<String, Object> params = new HashMap<String, Object>();
params.put("dates", yourlistofdates);
List<YourResultType> result = template.query(query, params, new YourResultTypeRowMapper());
That is all.

JDBC: in set condition: can I pass a set as single param?

In JDBC I can use question marks for query parameters, like this:
"SELECT * FROM users WHERE login = ?"
and then
ps.setString(1, "vasya");
But how can I query for list of logins:
"SELECT * FROM users WHERE login IN ?"
suppose, I have
List<String> logins = ...
What should I type there:
ps.setWhat(1, what);
I could rewrite query as:
"SELECT * FROM users WHERE login = ? OR login = ? OR login = ?"
and then call setString in loop, but I'd like to know if it is possible to pass a set of elements as single param in query.
Maybe there are vendor-specific extensions?
There are vendor specific ways to do that, therefore it would be good to know what database you use. I know solutions for PostgreSQL and H2. I implemented this feature in the H2 database, so that's what I know best:
H2 Database
PreparedStatement prep = conn.prepareStatement(
"select * from users where login in (select * from table(x int = ?))");
prep.setObject(1, new Object[] { "1", "2" });
ResultSet rs = prep.executeQuery();
PostgreSQL
WHERE login = ANY(?)
Then set the parameter to an array of values using PreparedStatement.setArray(..) (not setObject as for H2).
Look here for an overview of available options. As far as I can tell you, everyone is dynamically generating the necessary number of placeholder characters (with some optimizations).
There's a setArray method in PreparedStatement, but sometimes using it is not feasible. You might give it a try though.
If Spring's JDBCTemplate is an option, you could use automatic collection expansion as described here.
//---
String query = "SELECT * FROM users WHERE login = ?";
List<Login> list = new ArrayList<Login>();
Login login = null;
for(String param : conditions){
pStmt.setString(1,param);
rSet = pStmt.executeQuery();
if(rSet.next()){
login = new Login();
login.setName(rSet.getString(1));
list.add(login);
}
}
return list;
//---
conditions will be the list of item on basis of which you want to retrieve fields.

Categories