PLpgSQL 函数不返回匹配的标题
PLpgSQL function not returning matching titles
我正在尝试return电影名称和演职人员的数量时给出一个文本。当我输入字符串并使用 ilike 时,我的查询 return 没有匹配的标题。我之前创建了一个视图,其中包含要在函数中输入的电影标题和剧组人数。
我的代码是:
create or replace view movies_crew as
select movies.id, movies.title, principals.role
from movies
join principals on principals.movie_id=movies.id
where principals.role <> 'producer'
;
create or replace view movie_makers as
select movies_crew.title, count(movies_crew.title) as ncrew
from movies_crew
where movies_crew.title = 'Fight Club'
group by movies_crew.title;
CREATE or REPLACE function Q11(partial_title text)
RETURNS SETOF text
AS $$
DECLARE
title text;
BEGIN
for title in
select movie_makers.title, movie_makers.ncrew
from movie_makers
where movie_makers.title ilike '%%'
loop
return next movie_makers.title||'has'||movie_makers.ncrew||'cast and crew';
end loop;
if(not found) then
return next 'No matching titles';
end if;
END;
$$ LANGUAGE plpgsql;
select * from q11('Fight Club')
我的数据库是:https://drive.google.com/file/d/1NVRLiYBVbKuiazynx9Egav7c4_VHFEzP/view?usp=sharing
ilike '%%'
</code> 在单引号内时不会被插入,因此您正在搜索文字字符 $ 和 1.</p>
<p>您可以改为:</p>
<pre><code>ilike '%'||||'%'
撇开你的直接引用问题不谈(Jeff 已经正确解决),函数可以像这样更简单和更快:
CREATE or REPLACE FUNCTION q11(partial_title text)
RETURNS SETOF text
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY
SELECT m.title || ' has ' || m.ncrew || ' cast and crew'
FROM movie_makers m
WHERE m.title ~* ;
IF NOT FOUND THEN
RETURN NEXT 'No matching titles';
END IF;
END
$func$;
要点:
您的功能仍然有问题。对 movie_makers.title
和 movie_makers.ncrew
的引用不会那样工作。我修好了。
使用RETURN QUERY
代替循环。这样我们也根本不需要使用甚至声明任何变量。参见:
- How to return result of a SELECT inside a function in PostgreSQL?
可选择使用不区分大小写的正则表达式匹配运算符 ~*
。 (更简单,而不是更快。)
- Difference between LIKE and ~ in Postgres
无论哪种方式,您都可能想要转义特殊字符。参见:
- Escape function for regular expression or LIKE patterns
旁白:在已经选择 'Fight Club' 作为其唯一行的视图上进行筛选几乎没有意义。对于有意义的搜索,您不会使用这些视图 ...
我正在尝试return电影名称和演职人员的数量时给出一个文本。当我输入字符串并使用 ilike 时,我的查询 return 没有匹配的标题。我之前创建了一个视图,其中包含要在函数中输入的电影标题和剧组人数。 我的代码是:
create or replace view movies_crew as
select movies.id, movies.title, principals.role
from movies
join principals on principals.movie_id=movies.id
where principals.role <> 'producer'
;
create or replace view movie_makers as
select movies_crew.title, count(movies_crew.title) as ncrew
from movies_crew
where movies_crew.title = 'Fight Club'
group by movies_crew.title;
CREATE or REPLACE function Q11(partial_title text)
RETURNS SETOF text
AS $$
DECLARE
title text;
BEGIN
for title in
select movie_makers.title, movie_makers.ncrew
from movie_makers
where movie_makers.title ilike '%%'
loop
return next movie_makers.title||'has'||movie_makers.ncrew||'cast and crew';
end loop;
if(not found) then
return next 'No matching titles';
end if;
END;
$$ LANGUAGE plpgsql;
select * from q11('Fight Club')
我的数据库是:https://drive.google.com/file/d/1NVRLiYBVbKuiazynx9Egav7c4_VHFEzP/view?usp=sharing
ilike '%%'
</code> 在单引号内时不会被插入,因此您正在搜索文字字符 $ 和 1.</p>
<p>您可以改为:</p>
<pre><code>ilike '%'||||'%'
撇开你的直接引用问题不谈(Jeff 已经正确解决),函数可以像这样更简单和更快:
CREATE or REPLACE FUNCTION q11(partial_title text)
RETURNS SETOF text
LANGUAGE plpgsql AS
$func$
BEGIN
RETURN QUERY
SELECT m.title || ' has ' || m.ncrew || ' cast and crew'
FROM movie_makers m
WHERE m.title ~* ;
IF NOT FOUND THEN
RETURN NEXT 'No matching titles';
END IF;
END
$func$;
要点:
您的功能仍然有问题。对
movie_makers.title
和movie_makers.ncrew
的引用不会那样工作。我修好了。使用
RETURN QUERY
代替循环。这样我们也根本不需要使用甚至声明任何变量。参见:- How to return result of a SELECT inside a function in PostgreSQL?
可选择使用不区分大小写的正则表达式匹配运算符
~*
。 (更简单,而不是更快。)- Difference between LIKE and ~ in Postgres
无论哪种方式,您都可能想要转义特殊字符。参见:
- Escape function for regular expression or LIKE patterns
旁白:在已经选择 'Fight Club' 作为其唯一行的视图上进行筛选几乎没有意义。对于有意义的搜索,您不会使用这些视图 ...