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 以上内容。
我创建了一个用于过滤的函数
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 以上内容。