在plpgsql中动态编写,而不是像动态一样

时间:2013-09-11 06:20:50

标签: sql postgresql plpgsql dynamic-sql sql-like

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

请建议如何实现这一目标。

2 个答案:

答案 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;

~~!~~LIKENOT 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注入。