1

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;

现在我想像'ABCD%' 一样传递$ 1 ,即:

select check_regno(f1, "like 'ABCD%'")

这将给出error at $1

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

4

2 回答 2

1

正如@Igor 提到的,这很容易出错。我会更进一步:不要这样做。您邀请 SQL 注入。在 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;

~~并且是and!~~的 Postgres 运算符(您可以使用其中任何一个)。LIKENOT LIKE

称呼:

SELECT * FROM check_regno(TRUE, 'ABCD%');
SELECT * FROM check_regno(FALSE, 'DEFG%');
于 2013-09-13T00:01:50.637 回答
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 注入。

于 2013-09-11T08:16:11.843 回答