如何使用现有功能过滤记录?

时间:2015-11-16 07:03:42

标签: sql postgresql

我的功能如下(我的功能更复杂,但假设这是函数):

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

但是这个解决方案迫使我用循环写两次整个查询。

如果没有两次编写相同的代码,有没有办法做到这一点?

1 个答案:

答案 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作为null0传递,则or的第一部分将为true,而其他条件将不会被评估(可能会,因为SQL没有短路,但它不重要)。如果将p_months作为不同的内容传递,则or的第一部分将为false,因此第二部分必须为true才能返回正确的结果。

请注意,我还将函数从PL / pgSQL函数更改为纯SQL函数。这里没有必要在一个循环中进行缓慢而低效的逐行处理(除非你对代码进行了过多的混淆,以至于你忽略了实际在该循环中执行某事的部分)