Разширени функции като VARIADIC
или дори полиморфните типове вход и динамичният SQL са много мощни. Последната глава в този отговор предоставя разширен пример:
- Рефакторирайте функция PL/pgSQL, за да върнете резултатите от различни SELECT заявки
Но за прост случай като вашия, можете просто да използвате стойности по подразбиране за параметри на функцията. Всичко зависи от точните изисквания.
Ако въпросните колони са всички дефинирани NOT NULL
, това вероятно би било по-просто и по-бързо:
CREATE OR REPLACE FUNCTION update_site(_name text -- always required
, _city text DEFAULT NULL
, _telephone integer DEFAULT NULL)
RETURNS integer AS
$func$
BEGIN
IF _city IS NULL AND _telephone IS NULL THEN
RAISE WARNING 'At least one value to update required!';
RETURN; -- nothing to update
END IF;
UPDATE "Sites"
SET "City" = COALESCE(_city, "City")
, "Telephone" = COALESCE(_telephone, "Telephone")
WHERE "SiteName" = _name;
END
$func$ LANGUAGE plpgsql;
Прочетете за стойностите по подразбиране в ръководството!
За да избегна конфликти в имената между параметри и имена на колони, създавам навик да поставям префикс на входните параметри с _
. Това е въпрос на вкус и стил.
- Първият параметър
name
няма по подразбиране, тъй като е задължително по всяко време. - Други параметри могат да бъдат пропуснати.
- Изисква се поне едно или
WARNING
се повдига и нищо друго не се случва. UPDATE
ще промени само колоните за дадени параметри.- Може лесно да се разшири за N параметри.
Извикване на функция
ОтPostgres 9.5 :
Простият начин е спозиционна нотация за параметри. Това позволява само пропускане на най-десния параметър(и):
SELECT update_site('foo', 'New York'); -- no telephone
Наименована нотация позволява да се пропусне всяко параметър, който има стойност по подразбиране:
SELECT update_site(name => 'foo', _telephone => 123); -- no city
И двете могат да се комбинират всмесена нотация :
SELECT update_site('foo', _telephone => 123); -- still no city
В Postgres 9.4 или по-стари, :=
беше използван за присвояване в разговора:
SELECT update_site(name := 'foo', _telephone := 123);
SELECT update_site('foo', _telephone := 123);
Все още е валиден в Postgres 12 за обратна съвместимост, но по-скоро използвайте съвременната нотация.