SQL1:
select regno from student where regno **like 'ABCD%'**
这已成功运行。但是我如何动态地写出像'ABCD%'? 例如:
CREATE OR REPLACE FUNCTION check_regno(refcursor, character varying)
RETURNS refcursor AS
$BODY$
begin
select regno from student where regno $1
return $1;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
现在我想将 $ 1 传递给,如'ABCD%',即:
select check_regno(f1, "like 'ABCD%'")
这将给error at $1
:
请建议如何实现这一目标。
答案 0 :(得分:1)
正如@Igor所说,这很容易出错。我会更进一步:不要这样做。您邀请SQL注入。考虑一下related answer on dba.SE。
事实上,我在你的问题中没有看到任何保证动态SQL的东西。使用纯SQL函数并传递一个纯字符串值:
CREATE OR REPLACE FUNCTION check_regno(_like bool, _filter text)
RETURNS SETOF text AS
$func$
SELECT regno FROM student
WHERE CASE WHEN $1 THEN regno ~~ $2 ELSE regno !~~ $2 END
$func$ LANGUAGE sql;
~~
和!~~
是LIKE
和NOT LIKE
的Postgres运算符(您也可以使用)。
呼叫:
SELECT * FROM check_regno(TRUE, 'ABCD%');
SELECT * FROM check_regno(FALSE, 'DEFG%');
答案 1 :(得分:0)
尝试类似:
CREATE OR REPLACE FUNCTION check_regno(p_filter varchar)
RETURNS SETOF student.regno%TYPE AS
$BODY$
begin
return query execute 'select regno from student where regno'||p_filter;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
SELECT * FROM check_regno('like ''ABCD%''');
但是这种类型的动态SQL容易出错,并且可以允许SQL注入。