WHERE 子句中的 plpgsql 参数错误

Error in plpgsql parameters in WHERE clause

我创建了一个用于过滤的函数

CREATE OR REPLACE FUNCTION filtersearch(
    val1 text[] DEFAULT NULL::text[],
    val2 text[] DEFAULT NULL::text[],
    val3 text[] DEFAULT NULL::text[],
    val4 boolean DEFAULT NULL::boolean)
    RETURNS SETOF student_table
    LANGUAGE 'plpgsql'

AS $BODY$

DECLARE
   where_val text := '';
   result_text int;
BEGIN

    IF  = true THEN
        where_val := 'attendance = true';
        raise notice 'Value: %', where_val;
    END IF;
    
    
RETURN QUERY EXECUTE    
'SELECT * FROM student_table"
    WHERE (LOWER("student_name") = () OR  IS NULL)
    AND ((LOWER("subject") = ()) OR  IS NULL)
    AND ((LOWER("comments") ILIKE ) 
        OR ( IS NULL) 
        )
    '|| where_val ||'' USING where_val;
    --raise notice 'Value: %', result_text;
END 
$BODY$;

调用时出错,

ERROR: op ANY/ALL (array) requires array on right side

非常感谢我的代码中的任何建议或评论

这是我的 table

的示例数据
student_name subject professor comments attendance
Amelia Math Digory Kirkle TRUE
Benjamin Science Hari Seldon FALSE
Charlotte English Lee Everett TRUE
Amelia English Lee Everett FALSE

我是这样调用代码的

SELECT filtersearch(
    (array['Amelia, Charlotte']::text[]), 
    (NULL), 
    (NULL), 
    (true)
)

SQLstring里面的$1,$2,$3占位符引用了EXECUTE QUERY命令的USING子句传递的参数.您只传递一个参数,它是 '' 或字符串 'attendance = true' - 两者都不能用于 IN 条件。

因此您需要使用 USING 子句传递三个参数,但 不是 您附加到 SQL 查询的字符串。如果您使用 ILIKE,则无需在该条件下使用 lower()。您的 where_val 字符串还缺少 AND(或 OR

CREATE OR REPLACE FUNCTION filtersearch(
    val1 text[] DEFAULT NULL::text[],
    val2 text[] DEFAULT NULL::text[],
    val3 text[] DEFAULT NULL::text[],
    val4 boolean DEFAULT NULL::boolean)
    RETURNS SETOF student_table
    LANGUAGE plpgsql

AS $BODY$

DECLARE
   where_val text := '';
BEGIN

  IF  = true THEN
    where_val := 'AND attendance = true';
    raise notice 'Value: %', where_val;
  END IF;
    
  RETURN QUERY EXECUTE    
   'SELECT * 
    FROM student_table
      WHERE (LOWER(student_name) = ANY() OR  IS NULL)
      AND (LOWER(subject") = ANY () OR  IS NULL)
      AND (LOWER("comments") ILIKE ANY() OR  IS NULL)
     '|| where_val
  USING val1, val2, val3; -- do NOT pass where_val here
END 
$BODY$;

你真的不需要动态 SQL。您可以对布尔参数的前 3 个参数应用相同的逻辑。

CREATE OR REPLACE FUNCTION filtersearch(
    val1 text[] DEFAULT NULL::text[],
    val2 text[] DEFAULT NULL::text[],
    val3 text[] DEFAULT NULL::text[],
    val4 boolean DEFAULT NULL::boolean)
    RETURNS SETOF student_table
    LANGUAGE plpgsql

AS $BODY$
BEGIN

  RETURN QUERY
    SELECT * 
    FROM student_table
      WHERE (LOWER(student_name) = any(val1) OR val1 IS NULL)
        AND (LOWER(subject) = any(val2) OR val2 IS NULL)
        AND (comments ILIKE ANY(val3) OR val3 IS NULL)
        AND (attendance = val4 or val4 = false or val4 is null);
END 
$BODY$;

您甚至不需要 PL/pgSQL 以上内容。