私も同様の状況にありました-幅広いパラメータリストを持つ関数。いわゆる名前付きパラメータ 、パラメータの順序を尊重する必要はありません。コードは長くなりますが、(私は)より読みやすく、より堅牢になることを願っています。
CREATE TABLE tab(name text, surname text, address text, city text, zip text);
CREATE OR REPLACE FUNCTION public.fx(name text, surname text,
address text, city text, zip text)
RETURNS void
LANGUAGE plpgsql
AS $function$
BEGIN
INSERT INTO tab(name, surname, address, city, zip)
VALUES(fx.name, fx.surname, fx.address, fx.city, fx.zip);
-- ... some other logic
END;
$function$
この関数は、名前付きパラメータを使用して呼び出すことができます。 表記:
SELECT fx(name := 'Pavel', surname := 'Stehule',
address := 'Skalice 12', city := 'Benesov', zip := '12');
重要:間違ったタイプを使用すると-Postgresはメッセージを報告します:
postgres=# SELECT fx(name := 'Pavel', surname := 'Stehule', address := 'Skalice 12', city := 'Benesov', zip := 12); ERROR: function fx(name := unknown, surname := unknown, address := unknown, city := unknown, zip := integer) does not exist LINE 1: SELECT fx(name := 'Pavel', surname := 'Stehule', ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.
メッセージは有効ですが、クリーンではありません。これは、関数のオーバーロードサポートのコストです。他にも、長いパラメータリストを分割する方法、およびこれらの問題をより快適に見つける方法などのトリックがあります。
Postgresはカスタムタイプをサポートしています。あなたはそれを使うことができます:
CREATE TYPE person_type AS (name text, surname text);
CREATE TYPE address_type AS (address text, city text, zip text);
コンストラクター関数を書くことができます:
CREATE OR REPLACE FUNCTION public._person_type(name text, surname text)
RETURNS person_type
LANGUAGE plpgsql
AS $function$
DECLARE r person_type;
BEGIN
r.name = name;
r.surname = surname;
RETURN r;
END;
$function$
CREATE OR REPLACE FUNCTION public._address_type(address text, city text, zip text)
RETURNS address_type
LANGUAGE plpgsql
AS $function$ DECLARE r address_type;
BEGIN
r.address = address;
r.city = city;
r.zip = zip;
RETURN r;
END;
$function$
このシステムの作成にはいくつかの作業が必要であり、長寿命のシステムでのみ実用的です。一方で、将来のメンテナンス作業のコストを削減します。
CREATE OR REPLACE FUNCTION public.fx(p person_type, a address_type)
RETURNS void
LANGUAGE plpgsql
AS $function$
BEGIN
INSERT INTO tab(name, surname, address, city, zip)
VALUES(p.name, p.surname, a.address, a.city, a.zip);
-- ... some other logic
END;
$function$
現在、より多くの表記法(表記法の組み合わせ)が可能です:
postgres=# SELECT fx(_person_type('Pavel','Stehule'),
postgres(# _address_type('Skalice 12','Benesov', '25601'));
fx
----
(1 row)
コンストラクターはエラーのローカリゼーションに役立ちます:
postgres=# SELECT fx(_person_type('Pavel','Stehule'), _address_type('Skalice 12','Benesov', 25601)); ERROR: function _address_type(unknown, unknown, integer) does not exist LINE 2: _address_type('Skalice 12','Benesov', 25601)); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.