0

我是 pl/pgsql 的新手,正在尝试创建动态查询。我现在拥有的是用于测试的基本参数组合。当它正常工作时,我会逐渐添加更多的动态部分,以创建一个动态的、多合一的查询。

问题是这应该可以工作,但是我search_creator在 pgadmin4 中看到一个空的数据输出。这是代码

CREATE  FUNCTION search_creator(creator text)
  RETURNS TABLE(place_id bigint, place_geom geometry, event_name character(200)) AS
$$
BEGIN
    RETURN QUERY EXECUTE 
    'SELECT place.id, place.geom, event.name
     FROM person
     JOIN event_creator ON event_creator.person_id = person.id
     JOIN event ON event.id = event_creator.event_id
     JOIN cep ON cep.event_id = event.id
     JOIN place ON place.id = cep.place_id
     WHERE person.name LIKE $1'
    USING creator;
END;
$$
LANGUAGE plpgsql;

这就是我调用函数的方式select search_creator('mike');

如果有帮助,在数据库中,该person.id列是 type character(200)

如果它有帮助,当我修改函数以接受int作为输入并将WHERE部分更改为 时WHERE person.id = $1,它可以正常工作。我可以在 pgadmin 输出中看到实际结果。

我的文本变量有什么问题?是语法吗?

另外,我该怎么做WHERE person.name LIKE '%$1%'

4

3 回答 3

1

如果你跑

SELECT search_creator('mike');

该函数将执行

SELECT ... WHERE person.name LIKE 'mike'

这与

SELECT ... WHERE person.name = 'mike'

显然没有这样的记录。

要添加和附加%,您可以使用

EXECUTE 'SELECT ...
         WHERE person.name LIKE ' || quote_nullable('%' || creator || '%'); 
于 2018-01-22T18:10:20.940 回答
1

这就是我调用函数的方式select search_creator('mike');

由于函数返回一个集合(SRF,集合返回函数),调用它:

SELECT * FROM search_creator('mike');

如果有帮助,在数据库中, person.id 列是 type character(200)

它有助于。而且很痛。就像我之前提到的,你不想使用char(n)( character(n))。曾经。(也修好你的桌子。)读这个:

另外,我该怎么做WHERE person.name LIKE '%$1%'

各种技术,但您可以使用正则表达式匹配运算符进行简化,~无需前导和尾随通配符 -几乎; 对于任一运算符,特殊字符都需要单独处理:

CREATE FUNCTION search_creator(_creator text)
  RETURNS TABLE(place_id bigint, place_geom geometry, event_name text) AS
$func$
BEGIN
   RETURN QUERY EXECUTE 
   'SELECT pl.id, pl.geom, e.name
    FROM   person        pe
    JOIN   event_creator ec ON ec.person_id = pe.id
    JOIN   event         e  ON e.id = ec.event_id
    JOIN   cep           c  ON c.event_id = e.id
    JOIN   place         pl ON pl.id = c.place_id
    WHERE  pe.name ~ $1'  -- note the operator: ~
   USING $1;
END
$func$  LANGUAGE plpgsql;

看:

遵循并阅读链接的答案以及对手册的引用。

于 2018-01-22T19:45:13.903 回答
0

下面是一些工作示例(Iusednamed IN 变量代替数字引用,并format用于concat('%',t,'%')构建 LIKE 查询:

t=# create or replace function fa(t text) returns table (c text) as
$$
begin
return query execute format($q$select %L::text where 'test' like %L $q$,t,concat('%',t,'%'));
end;
$$ language plpgsql
;
CREATE FUNCTION
Time: 4.412 ms
t=# select * from fa('es');
 c
----
 es
(1 row)
于 2018-01-22T18:09:00.830 回答