I am trying to create a dynamic string and append it to where clause in postgresql byt I always get an error stating;
ERROR: syntax error at or near "4"
LINE 13: when 4 = ANY(stars) then appendtext := appendtext || ' ...
^
SQL state: 42601
Character: 332
This is the function
CREATE OR REPLACE FUNCTION public.reviewsbystartotal(
cid integer, stars integer[])
RETURNS integer
LANGUAGE 'plpgsql'
COST 100
VOLATILE PARALLEL UNSAFE
AS $BODY$
declare appendtext text := '';
BEGIN
case when 5 = ANY(stars) then appendtext := appendtext || ' and cr.generalrating >= 4.25'
when 4 = ANY(stars) then appendtext := appendtext || ' and cr.generalrating >= 3.25 and cr.generalrating <= 4.24'
when 3 = ANY(stars) then appendtext := appendtext || ' and cr.generalrating >= 2.5 and cr.generalrating <= 3.24'
when 2 = ANY(stars) then appendtext := appendtext || ' and cr.generalrating >= 1.75 and cr.generalrating <= 2.49'
when 1 = ANY(stars) then appendtext := appendtext || ' and cr.generalrating >= 1 and cr.generalrating <= 1.74'
else
RETURN (Select count(1) from companyreviews cr where cr.company=cid
and cr.internalapproval=true
|| appendtext);
END;
$BODY$;
I tried to concanate a string and append it where clause in postgresql.
2
Answers
The concatenation operator || should be placed outside the parentheses of the SELECT statement.
Here’s the corrected version of your function:
It appears that the OP intended to dynamically build and then execute a query to return the number of ratings a company for multiple discrete ranges. If no ranges are selected, then the query should return the total number of ratings for the company. The OP’s code defined the ranges as closed intervals. I’ve implemented them as half-open intervals to protect against potential gaps between ranges.
The following implements that capability as a PL/pgSQL function:
The desired behavior can be implemented as a SQL function without resorting to dynamic SQL as follows:
All column and variable references are qualified to protect against protential identifier ambiguity.
There is one known difference in behavior between the PL/pgSQL and SQL implementations: if all items in the stars array have values outside of the valid range of 1-5, then the PL/pgSQL version will return the count of all ratings for the company and the SQL version will return a count of 0.