Spring Hibernate and PostgresSQL Full Text Search - spring

How to implement FTS with Hibernate, Spring and PostgresSQL. Can I put some paramters in Hibernate #Formula annotation so I could put score as extra select paramter:
select *,
ts_rank_cd(to_tsvector(title || ' ' || code || ' ' || line1 || ' ' || postal || ' ' || city),
to_tsquery('LA | Los Anageles')) AS score
from customer
where score > 0
order by score desc;
and how to do it with Spirng Specifications, now I have:
if (!StringUtils.isEmpty(search)) {
spec = Objects.requireNonNull(spec).and((root, query, cb) -> cb.or(
cb.like(cb.lower(root.get(Customer_.title)), "%" + search.toLowerCase() + "%"),
cb.like(cb.lower(root.get(Customer_.code)), "%" + search.toLowerCase() + "%"),
cb.like(cb.lower(root.get(Customer_.address).get(Address_.line1)), search.toLowerCase() + "%"),
cb.like(cb.lower(root.get(Customer_.address).get(Address_.postal)), search.toLowerCase() + "%"),
cb.like(cb.lower(root.get(Customer_.address).get(Address_.city)), search.toLowerCase() + "%")
));
}
could I used at least cb.function withoud sorting by score?

You will have to implement a custom SQLFunction and register that under a name in Hibernate. You can then use the function by that name through cb.function.
Alternatively you should also be able to use the following:
cb.function("ts_rank_cd", String.class,
cb.function("to_tsvector", String.class,
cb.concat(...),
cb.function("to_tsquery", String.class, cb.literal("LA | Los Anageles"))
)
).as(Double.class);
This should result in SQL similar to this:
cast(ts_rank_cd(to_tsvector(title || ' ' || code || ' ' || line1 || ' ' || postal || ' ' || city), to_tsquery('LA | Los Anageles')) as double precision)

Related

Not getting multiple data for binding parameters in select statement in oracle [duplicate]

I have this query that I'm passing 2 parameters, COUNTRY_REGION parameter and COST_CENTER parameter
I have the possibility to pass both parameters at the same time COST_CENTER and COUNTRY_REGION..... Or pass one or the other... This part is OK.
You can see in the first image below
SELECT
dwg.GEOGRAPHY_ID as geographyId
,INITCAP (lower (dwc.COUNTRY_REGION)) as countryRegion
,INITCAP (lower (dwc.COUNTRY_NAME)) as countryName
,dp.PROJECT_ID as projectId
FROM
DATALAKE.DWL_GEOGRAPHIES dwg
,DATALAKE.DWB_PROJECT dp
,DATALAKE.DWL_GEOGRAPHY_COUNTRIES dwgc
,DATALAKE.DWL_COUNTRY dwc
,DATALAKE.DWB_PROJECT_FINANCIAL dpf
,DATALAKE.DWL_GOLIVE dgl
where dwg.geography_id = dp.project_geography_id
and dwg.geography_id = dwgc.geography_id
and dwc.country_id = dwgc.country_id
and dp.PROJECT_ID = dpf.PROJECT_ID
and dpf.PROJECT_ID = dgl.PROJECT_ID
and dpf.FLAG_ACTIVE = 1
and ((dp.cost_center = (:costCenter) and INITCAP (lower (dwc.COUNTRY_REGION)) = (:countryRegion))
or (:costCenter IS null and INITCAP (lower (dwc.COUNTRY_REGION)) = (:countryRegion))
or (dp.cost_center = (:costCenter) and :countryRegion IS null)
)
order by dwc.COUNTRY_REGION
But I WANT TO HAVE THE OPTION TO PASSA TWO OR MORE IN THE SAME PARAMETER as in the image below...
example:
COUNTRY_REGION: Peru, Chile, Argentina
or
COST_CENTER : 10500, 1000, ... , ....
I would like help, I've tried several things and I can't proceed, thank you very much.
You cannot pass multiple values with a single bind variable.
What you can do is pass in a single string that contains a delimited list and match a sub-string of the list to the value:
SELECT *
FROM table_name
WHERE ', ' || :country_region_list || ', ' LIKE '%, ' || country_region || ', %'
OR ', ' || :cost_centre_list || ', ' LIKE '%, ' || cost_centre || ', %'
Which would make your query:
SELECT dwg.GEOGRAPHY_ID as geographyId
, INITCAP(dwc.COUNTRY_REGION) as countryRegion
, INITCAP(dwc.COUNTRY_NAME) as countryName
, dp.PROJECT_ID as projectId
FROM DATALAKE.DWL_GEOGRAPHIES dwg
INNER JOIN DATALAKE.DWB_PROJECT dp
ON (dwg.geography_id = dp.project_geography_id)
INNER JOIN DATALAKE.DWL_GEOGRAPHY_COUNTRIES dwgc
ON (dwg.geography_id = dwgc.geography_id)
INNER JOIN DATALAKE.DWL_COUNTRY dwc
ON (dwc.country_id = dwgc.country_id)
INNER JOIN DATALAKE.DWB_PROJECT_FINANCIAL dpf
ON (dp.PROJECT_ID = dpf.PROJECT_ID)
INNER JOIN DATALAKE.DWL_GOLIVE dgl
ON (dpf.PROJECT_ID = dgl.PROJECT_ID)
WHERE dpf.FLAG_ACTIVE = 1
AND (
', ' || :costCenter || ', ' LIKE '%, ' || dp.cost_center || ', %'
OR :costCenter IS null
)
AND (
', ' || :countryRegion || ', '
LIKE '%, ' || INITCAP(dwc.COUNTRY_REGION) || ', %'
OR :countryRegion IS null
)
AND (:costCenter IS NOT NULL OR :countryRegion IS NOT NULL)
order by dwc.COUNTRY_REGION

Equivalent of Select #variable in Spring Data Jpa

I need to run a long query on a spring data jpa method call.
What is the equivalent of Select #sql in spring jpa.
I am getting exception when i try to execute it as a native query.
Below is the query that is working fine in SQL server
Declare #sql varchar(max) = 'select '
select #sql = #sql + 'sum(' + c.name + ')' + ' AS ' + c.name + ','
from sys.columns c
inner join sys.tables t on c.object_id = t.object_id
inner join sys.types ty on
c.user_type_id = ty.user_type_id
where
ty.name in ('bigint') and
t.name = 'my_used_features'
select #sql = LEFT(#sql,LEN(#sql)-1) + ' from my_used_features '
EXEC (#sql)
I want to write the same query as native query in my repository class.But I am getting exception like ....... EXEC (#sql)> starts a quoted range at 342, but never ends it.I am not able to figure out the issue.Can anyone please help me on what am I doing wrong.
#Query
(value="Declare #sql varchar(max) = 'select '\r\n"
+ " \r\n"
+ " select #sql = #sql + 'sum(' + c.name + ')' + ' AS ' + c.name + ',' \r\n"
+ " from sys.columns c\r\n"
+ " inner join sys.tables t on c.object_id = t.object_id\r\n"
+ " inner join sys.types ty on\r\n"
+ " c.user_type_id = ty.user_type_id\r\n"
+ " where\r\n"
+ " ty.name in ('bigint') and\r\n"
+ " t.name = 'my_used_features'\r\n"
+ " \r\n"
+ " select #sql = LEFT(#sql,LEN(#sql)-1) + ' from my_used_features ' \r\n"
+ " \r\n"
+ " EXEC (#sql)",nativeQuery=true)
Map<String,Integer> findSum();

ORA-00937: not a single-group group function, count function

select officer.forename || ' ' || Officer.surname || ' is working on : ' ||
count(crime.crime_id) "Officers Current Crimes"
From officer, crime
where officer.officer_id = crime.officer_id
order by crime.crime_id;
Can anyone tell me how to fix this error please, its something to do with the count function, thankyou in advance.
select officer.forename, Officer.surname || ' is working on : ' ||
count(crime.crime_id) "Officers Current Crimes"
From officer, crime
where officer.officer_id = crime.officer_id
GROUP BY officer.forename, Officer.surname;
You cant use a ORDER BY on non grouped column..

Spring JPA #Query where clause with 'like' and 'or'

I have the following query:
#Query("select c from Category c where ( (lower(c.name) like '%' || lower(:searchText) || '%') or (lower(c.description) like '%' || lower(:searchText)) || '%')")
My product is designed to run in multiple platform, I am getting an error on postgreSQL which is:
PSQLException: ERROR: argument of OR must be type boolean, not type
text.
Which is undestandable since the like clause return strings. But I wasn't able to perform the search in one query request. So the question is how can I perform a search where the where conditions refer to 2 differnt columns and use the 'like' operator.
The parentheses you have are not correct the following should work:
#Query("select c from Category c " +
"where (lower(c.name) like ('%' || lower(:searchText) || '%')) " +
" or (lower(c.description) like ('%' || lower(:searchText) || '%'))")

SSRS 2005 - Omitting Records

I have a stored proc that has several parameters. Most of them allow for multiple selections in a drop-down menu. They are: vOwner, vFunction, vSite, vStatus (all multiple selections allowed and the "Select All" is also enabled), and then vStartDate and vEndDate.
For some reason, when I choose "Select All" for every parameter, SSRS cuts off some of the records. It seems to report everything except records for the very last "owner." I'm looking for a clue as to why this might be happening. It happens when I select just one date's worth of data. It's as though that last owner isn't even being picked up as part of the data set.
Where SSRS is concerned, the settings are fairly simple. I have a data set that references the stored procedure (below), and one for each of the lookup tables i have (function, status, etc.) Any help is appreciated. Let me know if other information is needed. Thanks!
Stored Procedure:
#vOwner varchar(1000) = NULL,
#vFunction varchar(1000) = NULL,
#vStatus varchar(1000) = NULL,
#vLocation varchar(1000) = NULL,
#vBeginDate datetime = NULL,
#vEndDate datetime = NULL
AS
BEGIN
--Allow for multiple owners, functions, etc. to be selected in SSRS.
Select #vOwner = ', ' + #vOwner + ', '
create table #Owner
(
Owner varchar(1000)
)
Insert Into #Owner
Select ManagerLastName + ', ' + ManagerFirstName As Owner
From Managers
Where #vOwner Like '%, ' + ManagerLastName + ', ' + ManagerFirstName + ', %'
Group By ManagerLastName, ManagerFirstName
--Function
Select #vFunction = ', ' + #vFunction + ', '
create table #Function
(
Functions varchar(1000)
)
Insert Into #Function
Select Functions
From Functions
Where #vFunction Like '%, ' + Functions + ', %'
Group By Functions
--Status
Select #vStatus = ', ' + #vStatus + ', '
create table #Status
(
IssueStatus varchar(1000)
)
Insert Into #Status
Select IssueStatus
From IssueStatus
Where #vStatus Like '%, ' + IssueStatus + ', %'
Group By IssueStatus
--Sites
Select #vLocation = ', ' + #vLocation + ', '
create table #Sites
(
siteName varchar(1000)
)
Insert Into #Sites
Select siteName
From Sites
Where #vLocation Like '%, ' + siteName + ', %'
Group By siteName
Select
recID,
siteName
functions
From issueInput
Where
#vFunction Like '%, ' + functions + ', %'
And #vOwner Like '%, ' + ManagerLastName + ', ' + ManagerFirstName + ', %'
And #vStatus Like '%, ' + IssueStatus + ', %'
And #vLocation Like '%, ' + SiteName + ', %'
And (#vBeginDate Is Null Or #vBeginDate = 0 Or #vBeginDate <= Cast(Convert(varchar,(OpenDate),101) As datetime))
And (#vEndDate Is Null Or #vEndDate = 0 Or #vEndDate >= Cast(Convert(varchar,(OpenDate),101) As datetime))
Order by OpenDate
END
Is there a reason you using a stored procedure? It's possible to do what you want, but passing multiple values on a single parameter isn't natively supported by SQL Server. If you want to do this, you have to do some hack, which from the looks of your SQL, you have impelmented a work around.
If you embed the query in the rdl file, you can simply have an IN clause (i.e. IN(#vOwner)) and SSRS will insert the values into the query in a proper way such that it has the expected behavior. This way you are relying on something that was designed to work instead of having to work around a known limitation.
Looks like it wasn't a flaw in SSRS at all. After testing it out more in SSMS, I discovered that it was only the owner value that was being cut off at the end. I increased the #vOwner parameter from varchar(1000) to varchar(2000) and it is working fine now. I was simply passing too many characters into that parameter and it was getting truncated. Problem solved. Thanks to billinkc for that light bulb!

Resources