在 pl/pgsql 中使用文本会带来空的结果集
Using text in pl/pgsql brings empty set of results
我是 pl/pgsql 的新手,正在尝试创建动态查询。我现在拥有的是用于测试的参数的基本组合。当它正常工作时,我会逐渐添加更多动态部分,以创建一个动态的、多合一的查询。
问题是这应该可以工作,但我在 pgadmin4 中看到一个空的 search_creator
作为数据输出。这是代码
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 '
USING creator;
END;
$$
LANGUAGE plpgsql;
这就是我调用函数 select search_creator('mike');
的方式。
如果有帮助,在数据库中,person.id
列的类型为 character(200)
。
如果有帮助,当我修改函数以接受 int
作为输入并将 WHERE
部分更改为 WHERE person.id =
时,它可以正常工作。我可以在 pgadmin 输出中看到实际结果。
我的文本变量有什么问题?是语法吗?
此外,我怎样才能做类似 WHERE person.name LIKE '%%'
的事情?
下面是一些工作示例(我使用命名的 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)
如果你运行
SELECT search_creator('mike');
函数将执行
SELECT ... WHERE person.name LIKE 'mike'
与
相同
SELECT ... WHERE person.name = 'mike'
显然没有这样的记录。
要添加和添加 %
,您可以使用
EXECUTE 'SELECT ...
WHERE person.name LIKE ' || quote_nullable('%' || creator || '%');
This is how I call the function select search_creator('mike');
由于函数 returns a set (SRF, set-returning function), 调用它:
SELECT * FROM search_creator('mike');
If it helps, in the database, the person.id column is type character(200)
.
有帮助。而且很痛。像我,你不想用char(n)
(character(n)
)。曾经。 (同时修正你的 table。)阅读这个:
- Any downsides of using data type "text" for storing strings?
Also, how can I do something like WHERE person.name LIKE '%%'
?
各种技术,但您可以使用正则表达式匹配运算符 ~
进行简化,它在没有前导和尾随通配符的情况下也能实现同样的效果 - almost;需要为任一运算符单独处理特殊字符:
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 ~ ' -- note the operator: ~
USING ;
END
$func$ LANGUAGE plpgsql;
参见:
- Difference between LIKE and ~ in Postgres
- Escape function for regular expression or LIKE patterns
关注并阅读链接的答案和包含的手册参考。
我是 pl/pgsql 的新手,正在尝试创建动态查询。我现在拥有的是用于测试的参数的基本组合。当它正常工作时,我会逐渐添加更多动态部分,以创建一个动态的、多合一的查询。
问题是这应该可以工作,但我在 pgadmin4 中看到一个空的 search_creator
作为数据输出。这是代码
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 '
USING creator;
END;
$$
LANGUAGE plpgsql;
这就是我调用函数 select search_creator('mike');
的方式。
如果有帮助,在数据库中,person.id
列的类型为 character(200)
。
如果有帮助,当我修改函数以接受 int
作为输入并将 WHERE
部分更改为 WHERE person.id =
时,它可以正常工作。我可以在 pgadmin 输出中看到实际结果。
我的文本变量有什么问题?是语法吗?
此外,我怎样才能做类似 WHERE person.name LIKE '%%'
的事情?
下面是一些工作示例(我使用命名的 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)
如果你运行
SELECT search_creator('mike');
函数将执行
SELECT ... WHERE person.name LIKE 'mike'
与
相同SELECT ... WHERE person.name = 'mike'
显然没有这样的记录。
要添加和添加 %
,您可以使用
EXECUTE 'SELECT ...
WHERE person.name LIKE ' || quote_nullable('%' || creator || '%');
This is how I call the function
select search_creator('mike');
由于函数 returns a set (SRF, set-returning function), 调用它:
SELECT * FROM search_creator('mike');
If it helps, in the database, the person.id column is type
character(200)
.
有帮助。而且很痛。像我char(n)
(character(n)
)。曾经。 (同时修正你的 table。)阅读这个:
- Any downsides of using data type "text" for storing strings?
Also, how can I do something like
WHERE person.name LIKE '%%'
?
各种技术,但您可以使用正则表达式匹配运算符 ~
进行简化,它在没有前导和尾随通配符的情况下也能实现同样的效果 - almost;需要为任一运算符单独处理特殊字符:
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 ~ ' -- note the operator: ~
USING ;
END
$func$ LANGUAGE plpgsql;
参见:
- Difference between LIKE and ~ in Postgres
- Escape function for regular expression or LIKE patterns
关注并阅读链接的答案和包含的手册参考。