SQL 如何在postgresql中为可选参数编​​写函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39896329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-01 04:55:30  来源:igfitidea点击:

How to write function for optional parameters in postgresql?

sqlpostgresqlplpgsql

提问by indu

My requirement is write optional parameters to a function.Parameters are optional sometimes i will add or i will not pass parameters to function.Can anyone help me how to write function.

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

I am writing like

我写得像

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

i am passing parameters to Query,But my output is not expected.when i pass all three parameters my output is correct,otherwise it is not expected output.

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

回答by a_horse_with_no_name

You can define optional parameters by supplying a default value.

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

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;

You can "leave out" parameters from the end, so foo(), foo(1)or foo(1,2)are valid. If you want to only supply a parameter that is not the first you have to use the syntax that specifies the parameter names.

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

select foo(); 

returns: p_one=, p_two=42, p_three=foo

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

select foo(1); 

returns: p_one=1, p_two=42, p_three=foo

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

select foo(p_three => 'bar')

returns: p_one=, p_two=42, p_three=bar

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

回答by bitifet

Apart of the VARIADICoption pointed by @a_horse_with_no_name, which is only a syntax sugar for passing an array with any number of elements of the same type, you can'tdefine a function with optional parameters because, in postgres, functions are identified not only by its name but also by its arguments and the types of them.

除了@a_horse_with_no_name指向的VARIADIC选项,它只是传递具有任意数量相同类型元素的数组的语法糖,您不能定义具有可选参数的函数,因为在 postgres 中,函数不仅被标识通过它的名字,还有它的参数和它们的类型。

That is: create function foo (int) [...]and create function foo (varchar) [...]will create differentfunctions.

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

Which is called when you execute, for example, select foo(bar)depends on bardata type itself. That is: if it is an integer, you will call the first one and if it is varchar, then second one will be called.

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

More than that: if you execute, for example, select foo(now()), then a function not existsexception will be triggered.

更重要的是:如果执行,例如select foo(now()),那么函数不存在异常将被触发。

So, as I said, you can't implement functions with variable arguments, but you can implement multiple functions with the same name and distinct argument (an/or type) sets returning the same data type.

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

If you (obviously) doesn't want to implement the function twice, the only thing you need to do is to implement a "master" function with all possible parameters and the others (which have fewer parameters) only calling the "master" one with default values for the non received parameters.

如果您(显然)不想两次实现该函数,那么您唯一需要做的就是实现一个具有所有可能参数的“主”函数,而其他(参数较少)仅调用“主”函数使用未接收参数的默认值。

回答by Kiry Meas

As an option, I got a function i tested with Navicat App: CREATE OR REPLACE FUNCTION "public"."for_loop_through_query"(sponsor_name varchar default 'Save the Children')It generates me this. (Note: Please look at the parameter difference) CREATE OR REPLACE FUNCTION "public"."for_loop_through_query"("sponsor_name" varchar='Save the Children'::character varying)

作为一个选项,我得到了一个我用 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;