如何在postgresql中编写可选参数的函数?

时间:2016-10-06 12:42:44

标签: sql postgresql plpgsql

我的要求是为函数编写可选参数。参数是可选的,有时候我会添加或者我不会将参数传递给函数。任何人都可以帮我编写函数。

我写的就像

select * 
from test 
where field3 in ('value1','value2') 
 and ($1 is null or field1 = $1) 
 and ($2 is null or field2 = $2) 
 and ($3 is null or field3 = $3);

我将参数传递给Query,但我的输出不是预期的。当我传递所有三个参数时,我的输出是正确的,否则它不是预期的输出。

3 个答案:

答案 0 :(得分:38)

您可以通过提供默认值来定义可选参数。

create function foo(p_one integer default null, 
                    p_two integer default 42, 
                    p_three varchar default 'foo')
  returns text
as
$$
begin
    return format('p_one=%s, p_two=%s, p_three=%s', p_one, p_two, p_three);
end;
$$
language plpgsql;

你可以"省略"最后的参数,因此foo()foo(1)foo(1,2)有效。如果您只想提供不是第一个参数,则必须使用指定参数名称的语法。

select foo(); 

返回:p_one=, p_two=42, p_three=foo

select foo(1); 

返回:p_one=1, p_two=42, p_three=foo

select foo(p_three => 'bar')

返回:p_one=, p_two=42, p_three=bar

答案 1 :(得分:6)

除了@a_horse_with_no_name指向的VARIADIC选项,它只是传递具有任意数量相同类型的数组的语法糖,你可以' t 使用可选参数定义一个函数,因为在postgres中,函数不仅通过其名称而且通过其参数及其类型来识别。

即:create function foo (int) [...]create function foo (varchar) [...]将创建不同的功能。

执行时调用的内容,例如select foo(bar)取决于 bar 数据类型本身。也就是说:如果它是一个整数,你将调用第一个,如果它是varchar,那么将调用第二个。

不仅如此:例如,如果执行select foo(now()),则函数不存在将触发异常

所以,正如我所说,你不能用变量参数实现函数,但是你可以实现具有相同名称和不同参数(和/或类型)的多个函数集返回相同的数据类型

如果你(显然)不希望两次实现该功能,你唯一需要做的就是实现一个带有所有可能参数的“主”功能和其他参数(参数较少)只调用“ master“具有未接收参数的默认值的那个。

答案 2 :(得分:0)

作为一种选择,我得到了使用Navicat App测试的功能: CREATE OR REPLACE FUNCTION "public"."for_loop_through_query"(sponsor_name varchar default 'Save the Children') 它产生了我这一点。 (注:请看参数差异) CREATE OR REPLACE FUNCTION "public"."for_loop_through_query"("sponsor_name" varchar='Save the Children'::character varying)

 CREATE OR REPLACE FUNCTION "public"."for_loop_through_query"("sponsor_name" varchar='Save the Children'::character varying)
  RETURNS "pg_catalog"."void" AS $BODY$
DECLARE
    rec RECORD;
BEGIN
    FOR rec IN SELECT
      companies."name" AS org_name,
      "sponsors"."name" AS sponsor_name
      FROM
      "donor_companies"
      JOIN "sponsors"
      ON "donor_companies"."donor_id" = "sponsors"."id" 
      JOIN companies
      ON "donor_companies"."organization_id" = companies."id"
      WHERE
      "public"."sponsors"."name" = sponsor_name
    LOOP
    RAISE NOTICE '%', rec.org_name;
  END LOOP;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;