我的功能如下(我的功能更复杂,但假设这是函数):
CREATE OR REPLACE FUNCTION A(id integer)
RETURNS a_type AS
$BODY$
declare
a_type ROW;
begin
FOR ROW IN
select * from table_1 where x_id=id;
LOOP
return next row;
end loop;
return;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
我想将功能更改为recive 2 parmeters。第二个是一个数字,它告诉我们今天要回去几个月:
我可以将功能更改为:
CREATE OR REPLACE FUNCTION A(id integer, months integer)
RETURNS a_type AS
$BODY$
declare
a_type ROW;
begin
if months>0 then:
FOR ROW IN
select * from table_1 where x_id=id and date > CURRENT_DATE - INTERVAL '3 months';
LOOP
return next row;
end loop;
return;
else:
FOR ROW IN
select * from table_1;
LOOP
return next row;
end loop;
return;
end;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
但是这个解决方案迫使我用循环写两次整个查询。
如果没有两次编写相同的代码,有没有办法做到这一点?
答案 0 :(得分:1)
这样的事情:
create or replace function a(p_id integer, p_months integer)
returns setof table_1
as
$$
select *
from table_1
where x_id = p_id
and ( coalesce(p_months,0) <= 0 or
some_date > current_date - interval '1' month * p_months );
$$
language sql;
如果将p_months
作为null
或0
传递,则or
的第一部分将为true,而其他条件将不会被评估(可能会,因为SQL没有短路,但它不重要)。如果将p_months
作为不同的内容传递,则or
的第一部分将为false,因此第二部分必须为true才能返回正确的结果。
请注意,我还将函数从PL / pgSQL函数更改为纯SQL函数。这里没有必要在一个循环中进行缓慢而低效的逐行处理(除非你对代码进行了过多的混淆,以至于你忽略了实际在该循环中执行某事的部分)