SpringBoot-Single value to multiple parameter using PostgreSQL - postgresql

PostgreSQL Query
select date,count(*) from table1
where (DATE_PART('day', current_date::timestamp - table1.date::timestamp ))
<(SELECT value from keyvaluepair where priority='Important')
and priority = 'Important' group by date
order by date
I will be calling from api where
http://localhost:8080/get/getDates?priority=Important
I will be passing as ? in both places as shown
select date,count(*) from table1
where (DATE_PART('day', current_date::timestamp - table1.date::timestamp))
<(SELECT value from keyvaluepair where priority=?)
and priority = ? group by date
order by date
I'm getting error like this
No value specified for parameter 2.; nested exception is org.postgresql.util.PSQLException: No value specified for parameter 2.
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback;
In java I'm just getting this query data date and count.
public Map<String,Object> getDates(String priority) {
Map<String,Object> map = new Map<String,Object>();
List<Object> count = new ArrayList<Object>();
List<Object> date = new ArrayList<Object>();
try {
jdbcTemplate.query(query, new Object[] { priority }, new RowMapper<Object>() {
#Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
date.add(rs.getString("date"));
count.add(rs.getInt("count"));
return null;
}
});
} catch (DataAccessException e) {
e.printStackTrace();
}
return map;
}
How to give priority once and use it twice in query?

select t1.date,count(*) from table1 t1
where (DATE_PART('day', current_date::timestamp - t1.date::timestamp ))
<(SELECT value from keyvaluepair k where k.priority=t1.priority)
and t1.priority = 'Important' group by t1.date
order by t1.date
This changes in query helped me in resolving error which I had as shown
No value specified for parameter 2.; nested exception is org.postgresql.util.PSQLException: No value specified for parameter 2.
org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback;
where two column names of table are same and I have to pass value once for all parameters as in link show below
http://localhost:8080/get/getDates?priority=Important
select t1.date,count(*) from table1 t1
where (DATE_PART('day', current_date::timestamp - t1.date::timestamp ))
<(SELECT value from keyvaluepair k where k.priority=t1.priority)
and t1.priority = ? group by t1.date
order by t1.date
here in this link single value that is priority Important is taken to query where it is used for both tables parameter of same column name.

Related

Why does this JPQL fail with message "You have attempted to set a parameter at position x which does not exist in this query string"?

I have the following named query:
#NamedQueries({
#NamedQuery(name ="Movies.findByTitle", query = "SELECT m FROM Movies m WHERE m.title = :title")
})
When I try to execute it as follows:
public List<T> findByTitle(String title) {
return getEntityManager().
createNamedQuery("Movies.findByTitle").
setParameter("findByTitle", title).
getResultList();
}
Then I get the following exception:
You have attempted to set a parameter value using a name of findByTitle that does not exist in the query string SELECT m FROM Movies m WHERE m.title = :title.
How is this caused and how can I solve it?
You need to set a correct parameter name.
You can see in your query the parameter is named "title" not "findByTitle".
setParameter("findByTitle", title) change this to setParameter("title", title)

sqflite IN operator with AND operator

I have following query which select from employee table where name is "max" and ID not in 123 and 444.
Not in IDs can grow in future. But I am receiving error as
Error
( 8023): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: DatabaseException(near "?": syntax error (code 1 SQLITE_ERROR): , while compiling:
Query
List<String> a = [];
a.add("123");
a.add("444");
var table = await mydb.rawQuery(
"SELECT value from employee WHERE employeename = ? AND id NOT IN ? ORDER BY timestamp DESC",
["max", a]);
If the LIST is unpredictable, one way is that you can use JOIN to create your select statement with required value of NOT IN. Below is one sample.
void main() {
List<String> a = [];
a.add("123");
a.add("444");
var select =
'SELECT value from employee WHERE employeename = ? AND id NOT IN (\'' +
(a.join('\',\'')).toString() +
'\') ORDER BY timestamp DESC';
var table = await mydb.rawQuery(select, ["max"]);
}
If you print the variable select you will get
SELECT value from employee WHERE employeename = ? AND id NOT IN ('123','444')
ORDER BY timestamp DESC.
Then you can pass the above statement to rawquery and get your result.
P.S:Use your single quote and double quote accordingly.
I'd go for #arun-palanisamy 's solution, see his comment. Props go to him. I just tried the following -- with Groovy/Postgres, but the error seems to be the same, so you might want to give it a try:
String[] a = ['123', '444']
// your code, throws 'ERROR: syntax error at or near "$2"':
// def table = sql.execute("SELECT value from employee WHERE employeename = ? AND id NOT IN ? ORDER BY timestamp DESC", ["max", a])
// code of arun-palanisamy, compiles:
def table = sql.execute("SELECT value from employee WHERE employeename = ? AND id NOT IN (${a.join(', ')}) ORDER BY timestamp DESC", ["max", a])
Side notes:
You might want to try a different type for a, such as Array in my code, or even a HashMap.
There are examples (like here) where the number of ? are generated dynamically.
Update: Go for this answer, we posted simultaneously

how to write hstore column in where clause of spring data jpa query

I am facing a problem in writing the "hstore" type column in where clause of spring data jpa query.
#Transactional(readOnly = true)
#Query(
value = "select ld from LocationData ld inner join fetch ld.assetData ad where ld.assetId in (:assetIds) and ld.orgId = :orgId and ld.eventTimestamp between :startDate and :endDate and ad.source in (:source) and
ad.attr -> 'CorrelationId' is not null",
countQuery = "select count(ld) from LocationData ld inner join ld.assetData ad where ld.assetId in (:assetIds) and ld.orgId = :orgId and ld.eventTimestamp between :startDate and :endDate and ad.source in (:source) and ad.attr -> 'CorrelationId' is not null""
)
Page<LocationData> findByAssetIdInAndOrgIdAndEventTimestampBetween(#Param("assetIds") List<Long> assetIds,
#Param("orgId") Integer orgId,
#Param("startDate") Long startEventTimestamp,
#Param("endDate") Long endEventTimeStamp,
#Param("source") List<String> source,
Pageable pageable);
In the above query "attr" is a hstore type column. I have a key by name CorrelationId in attr column. I want to select to those where CorrelationId key is not null. I tried with "ad.attr -> 'CorrelationId' is not null" in pgAdmin it is working pretty fine but in spring data jpa query it is not working and throwing error as invalid identifier.
Can anyone help me on this.
If JPA doesn't like the "->" operator, you can try the functional forms
fetchval(ad.attr,'CorrelationId') IS NOT NULL
or
defined(ad.attr,'CorrelationId')

How can i ignore: PSQLException: The column name clothStyle was not found in this ResultSet

I created a a query to only get 4 items from a row in a table which does not include the column cloth style, so i understand why i get the error, but how can i tell Spring Jpa or JPA it is on purpose. and i just want the id, name and color table ?
this is my code:
#RequestMapping(value = "/query/material",method = RequestMethod.GET)
public String QueryMaterialTable(HttpServletRequest request){
DataTableRequest<Material> dataTableInRQ = new DataTableRequest<Material>(request);
PaginationCriteria pagination = dataTableInRQ.getPaginationRequest();
String baseQuery = "SELECT id as id, time as time, name as name, color as color, price as price, (SELECT COUNT(1) FROM MATERIAL) AS totalrecords FROM MATERIAL";
String paginatedQuery = AppUtil.buildPaginatedQuery(baseQuery, pagination);
System.out.println(paginatedQuery);
Query query = entityManager.createNativeQuery(paginatedQuery, Material.class);
#SuppressWarnings("unchecked")
List<Material> materialList = query.getResultList();
DataTableResults<Material> dataTableResult = new DataTableResults<Material>();
dataTableResult.setDraw(dataTableInRQ.getDraw());
dataTableResult.setListOfDataObjects(materialList);
if (!AppUtil.isObjectEmpty(materialList)) {
dataTableResult.setRecordsTotal(String.valueOf(materialList.size())
);
if (dataTableInRQ.getPaginationRequest().isFilterByEmpty()) {
dataTableResult.setRecordsFiltered(String.valueOf(materialList.size()));
} else {
dataTableResult.setRecordsFiltered(String.valueOf(materialList.size()));
}
}
return new Gson().toJson(dataTableResult);
}
If I got the question right, your problem is with the following two lines:
Query query = entityManager.createNativeQuery(paginatedQuery, Material.class);
List<Material> materialList = query.getResultList();
You have various options to fix this:
provide a complete column list, i.e. provide the missing column in the SQL statement and just make them NULL;
Don't use Material but a new class that has the matching attributes.
Don't use a native query but JPQL and a constructor expression.
Use a ResultTransformer.
Use Spring Data and a Projection.
Use a Spring JdbcTemplate.

JPQL, How to execute a query without a matched entity type?

Say I get an entity from database, employee, and it has 3 attributes :
1.name(String)
2.id(String)
3.department(String).
Now I want to do a group-function query like: select e.department, count(e) from employee e group by e.department. I'm using EntityManager to create an executable query but question is no such entity fits the result, what should I do to do such a query and obtain the result?
Your query will return results like this:
Department Count
Dept1 10
Dept2 20
Assuming you have a ResultSet object:
while(rs.next()){
String dept = rs.getString(1); //You can use column name if its defined
int count = rs.getInt(2);
}
select e.department, count(e) from employee e group by e.department
This jpql will give result as Object[] .
Then cast the result to required object.
for (Object[] o : resultList) {
String department = (String) o[0];
int e = (Integer) o[1];
System.out.println(department + " : " + e);
}
I think this will help you.