jdbctemplate equivalent of following query - oracle

I have a long list of argument which I need to send to oracle database. I was able to do it by splitting the query but I am unable to find a way to do similar using jdbcTemplate. my query is:
select name,age from person where personId in (A1,F2,D3...G900)
or personId in (A901, C902 , ... R1800)
or personId in (A1801,G1802 .... H2700)
or personId in (P2701, G2702 ... R3600)
or since oracle allow more than 1000 touple but does not allow in so JDBC equivalent for
SELECT field1, field2, field3
FROM table1
WHERE (1, name) IN ((1, value1), (1, value2), (1, value3),.....(1, value5000));

List<Map<String, Object>> findPeeps(List<Long> personIds) {
String sql = "select name,age from person where personId in (:personIds)";
return namedParameterJdbcTemplate.queryForList(sql, new MapSqlParameterSource("personIds", personIds));
}

As #zaki said you can use that but the error that you are getting is from Oracle since there is limit of records you can put in WHERE IN clause. You can try something like this
insert into TEMP values ( ... );
select * from T where (a,b) in (select x,y from temp);
delete from TEMP;

Related

List of multiple column condition in query (kind of batch)

when trying to search with single record then this query works
#Query(value = "select * from table t where t.column1 = :column1 and t.column2 = :column2 and t.column3 = :column3")
Flux<Invoice> findByMultipleColumn(#Param("column1”) String column1, #Param("column2”) String column2, #Param("column3”) String column3);
But when I have list of criterias instead of a single row condition then I have to loop over the list of criterias & call the above query multiple times which is not feasible solution.
Sudo code
for (Criteria criteria : criteriaList) {
repository.findByMultipleColumn(criteria.getColumn1(), criteria.getColumn2(), criteria.getColumn3());
}
What I am trying to find a way to solve the above query for multiple LIST of all the 3 column criteria pair, something like below (this is not working solution)
#Query(value = "select * from table t where t.column1 = :column1 and t.column2 = :column2 and t.column3 = :column3")
Flux<Invoice> findByMultipleColumn(#Param List<Table> table);
Is there any way somehow we can try to achieve the above case?
Would be doable if column1, 2 and 3 were Embedded, then you could do
#Query(select * from Entity where embeddedProperty in (:values))
Flux<Entity> findByEmbeddedPropertyIn(Collection<EmbeddedClas> values);
Which would generate the following native SQL clause
Where (column1, column2, column3) in ((x, y, z), ...)
If you don't want to pack these fields i to an embeddable class, you can also try to do a workaround
#Query(select * from Entity where Concat(column1, ';', column2, ';', column3) in (:parametersConcatrenatedInJava)
Flux<Entity> findBy3Columns(Collection<String> parametersConcatrenatedInJava);
It's ofcourse not bulletproof, all three columns could have ";" as their values, this might be problematic if their type is not string, etc.
Edit.:
Third option is to use specification api. Using the criteria builder you can concatenate multiple and / or queries. And pass that specification as an argument to the repository that extends JpaSpecificationExecutor (if you're fetching whole entities) or an entity manager if you're using projections. Read more about specifications

How to select different fields using .Concat for Union All query

I’m doing some preliminary work getting data consumption ready from a webAPI controller in MVC. I’m using a linq query that mimics a union query that uses two joins. However, I need the select statement to ask for a different field on each side of the union. This works fine in SSMS when I run the query, but when I create the query in linq it will not allow the fields to be different. It gives an error saying that each anonymous type requires a receiver of the same type. This is referring to the two anonymous types created via select new { }… Here’s the two queries.
In SQL:
Select m.Last_Name, first_name, m.dc_number, Dept_Job as JobOrStatus FROM
Master_Roster m
INNER JOIN Class_Assignment a on m.dc_number = a.dc_number
where a.subject_am = 'y1'
AND Start_Date_AM <= '1/31/18'
UNION ALL
Select m.Last_Name, first_name, m.dc_number, status_am FROM Master_Roster m
INNER JOIN Attend_am_y1 at on m.dc_number = at.dc_number
where at.class_date_am >= '1/1/18'
AND at.class_date_am <= '1/31/18'
ORDER BY Last_Name
In linq:
(from m in db.Master_Roster
join c in db.Class_Assignment
on m.dc_number equals c.dc_number
orderby m.Last_Name
where c.Subject_AM == "y1"
select new { m.dc_number, m.Last_Name, m.First_Name }).Concat(
from m in db.Master_Roster
join a in db.attend_am_y1 on m.dc_number equals a.dc_number
orderby m.Last_Name
where a.class_date_am >= date1 &&
a.class_date_am <= date2
select new { m.dc_number, m.Last_Name, m.First_Name });
If I were to add dept_job and status_am to the linq query, it throws aforementioned error. I’d like to do this without using a stored procedure. Any ideas?
Instead of putting into 2 anonymous types, put into the same viewmodel and concat. Eg:
Internal Class ConcatViewModel{
public int DcNumber {get;set;}
public string LastName {get;set;)
// etc...
}
Then:
select new ConcatViewModel{
DcNumber = m.dc_number,
LastName = m.Last_Name,
FirstName = m.First_Name,
Status = m.Dept_Job
}
and
select new ConcatViewModel{
DcNumber = m.dc_number,
LastName = m.Last_Name,
FirstName = m.First_Name,
Status = m.status_am
}
(assuming that status_am and Dept_Job are the same underlying type)

Joining 4 tables using nested queries Oracle

I am using nested queries to achieve this:
Basically, I have this:
employee table:
employee_id, locale
audience table
employee_id
country table
country_name,country_code
country_language
country_code, geo
I need this: employee_id,audience_id,country_name,locale from these tables that come under "APAC" geo:
I have this query:
SELECT employee_id
FROM audience
WHERE employee_id IN
(SELECT employee_id
FROM employee
WHERE LOCALE IN
(SELECT LOCALE
FROM COUNTRY_LANGUAGE
WHERE COUNTRY_CODE IN
(SELECT COUNTRY_CODE
FROM COUNTRY
WHERE GEO='apac')
)
)
ORDER BY employee_id);
This is throwing this error: "SQL command not properly ended"
Also, will this query produce right results if run properly? If not, can u suggest something else?
Used this as joins. Did not return anything:
select a.employee_id,
a.locale,
b.audience_id,
c.LOCALE_CODE,
d.COUNTRY_NAME
from employee a,
audience b,
country_language c,
country d
where
a.employee_id=b.employee_ID
and d.geo='apac'
and d.country_code=c.country_code
and a.locale=c.LOCALE_CODE;
You can try to use UNION SELECT

How can I convert a sql query to Linq query?

SELECT DISTINCT Title,
ProductDescription,
COUNT(1) as Duplicate
FROM DB_Deals
GROUP BY Title, ProductDescription
HAVING COUNT(1) > 1;
Well, if by EF, you mean making a query using LINQ to Entities...
from deal in context.DB_Deals
group deal by new { deal.Title, deal.ProductDescription } into dealGroup
where dealGroup.Count() > 1
select new {
dealGroup.Key.Title,
dealGroup.Key.ProductDescription,
Duplicate = dealGroup.Count(),
}
Assuming, context is your DbContext, and DB_Deals is your mapped table name.
See
Entity Framework T-Sql "having" Equivalent
Group By Multiple Columns

How to write Order by expression in JPQL

PostgreSQL and MySQL offers to write expression into ORDER BY clause in SQL query. It allows to sort items by some column but the special values are on the top. The SQL looks like this one. ( works in Postgres )
select * from article order by id = 4, id desc;
Now I want to write it in the JPQL but it doesn't work. My attempt is:
#NamedQuery(name = "Article.special", query = "SELECT a FROM Article a ORDER BY ( a.id = :id ) DESC, a.id DESC")
This is JPA 1.0 with Hibernate driver. Application server throws this exception on deploy.
ERROR [SessionFactoryImpl] Error in named query: Article.special
org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node: = near line 1, column 73 [SELECT a FROM cz.cvut.fel.sk.model.department.Article a ORDER BY ( a.id = :id ) DESC, a.id DESC]
at org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
Thanks a lot.
For a named query, (ORDER BY ( a.id = :id ) or ORDER BY (:id )) won't work as DSC/ASC can't be parametrized at run-time.
1) Dynamic way if ordering element varies at runtime.
String query = "SELECT a FROM Article a ORDER BY "+orderElement+" DESC, a.id DESC";
entityManager.createQuery(query).getResultList();
2) Static way in entity bean if ordering element is fixed.
Field level:
#OrderBy("id ASC")
List<Article> articles;
Method level:
#OrderBy("id DESC")
public List<Article> getArticles() {...};

Resources