Как написать функцию для дополнительных параметров в postgresql?
Мое требование - писать необязательные параметры функции. Параметры необязательны, иногда я добавлю или я не буду передавать параметры функции. Может кто-нибудь мне помочь, как написать функцию.
Я пишу как
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, но мой вывод не ожидается. Когда я передаю все три параметра, мой вывод верен, иначе это не ожидается.
Ответы
Ответ 1
Вы можете определить необязательные параметры, указав значение по умолчанию.
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
Ответ 2
Помимо опции VARIADIC, указанной параметром @a_horse_with_no_name, которая является всего лишь синтаксическим сахаром для передачи массива с любым количеством элементов того же типа, вы не можете определить функцию с необязательные параметры, потому что в postgres функции идентифицируются не только по имени, но и по аргументам и их типам.
То есть: create function foo (int) [...]
и create function foo (varchar) [...]
создадут разные функции.
То, что вызывается при выполнении, например, select foo(bar)
, зависит от самого типа данных бара. То есть: если это целое число, вы будете вызывать первое, а если это varchar, то будет вызываться второе.
Более того: если вы выполните, например, select foo(now())
, то будет сработать исключение не существующей функции.
Итак, как я уже сказал, вы не можете реализовать функции с переменными аргументами, , но вы можете реализовать несколько функций с одинаковыми именами и наборами различных аргументов (и/или типов), возвращающих один и тот же тип данных.
Если вы (очевидно) не хотите реализовывать функцию дважды, единственное, что вам нужно сделать, - это реализовать функцию "master" со всеми возможными параметрами, а остальные (которые имеют меньше параметров), вызывая только функцию "master" с значения по умолчанию для не полученных параметров.
Ответ 3
Как вариант, я получил функцию, которую я тестировал с помощью приложения Navicat:
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;