関数パラメーターと動的 SQLにデフォルト値を使用する...
デモ機能
CREATE OR REPLACE FUNCTION create_patient(
_name text = NULL -- always updated, NULL if not provided
,_email text = NULL
,_phone text = NULL
,_password text = NULL
,_field1 text = NULL -- variable parameters
,_field2 text = NULL
,_field3 timestamp = NULL
,_language text = NULL
,_cols text[] = '{field1,field2,field3,language}'
,OUT _pid text
,OUT _id int)
RETURNS record AS
$func$
BEGIN
EXECUTE format(
'INSERT INTO patients (field1, field2, field3, name, email, phone)
VALUES (%s, %s, %s, $4, $5, $6 )
RETURNING id'
,CASE WHEN 'field1' = ANY(_cols) THEN '$1' ELSE 'DEFAULT' END
,CASE WHEN 'field2' = ANY(_cols) THEN '$2' ELSE 'DEFAULT' END
,CASE WHEN 'field3' = ANY(_cols) THEN '$3' ELSE 'DEFAULT' END)
INTO _pid -- return value, also used in 2nd insert
USING _field1, _field2, _field3, _name, _email, _phone;
EXECUTE format(
'INSERT INTO users (username, password, type, pid, phone, language)
VALUES ($1, $2, $$patient$$, $3, $4, %s )
RETURNING id'
,CASE WHEN 'language' = ANY(_cols) THEN '$4' ELSE 'DEFAULT' END)
INTO _id -- return value
USING _email, _password, _pid, _phone, _language;
END
$func$ LANGUAGE plpgsql;
電話
SELECT * FROM create_patient('myname','myemail','myphone','mypassword'
,'myfield1','myfield2',NULL,'English','{field2,language,field1}'::text[]);
関数は名前付きパラメーターを使用し、それぞれにデフォルト値があるため、次のように呼び出すこともできます。
SELECT * FROM create_patient(_name := 'myname');
null 以外の値が必要な場合はテーブルで機能しない可能性がありますが、名前付きパラメーターを指定すると、デフォルトでパラメーターを省略できることを示します。省略されたパラメーターは、宣言されたとおりのデフォルト値を取ります (列のデフォルトと混同しないでください)。この関連する回答の詳細:
可変数の入力パラメーターを持つ関数
主なポイント
コマンドのDEFAULT
キーワードINSERT
を利用します。システムにテーブルの列のデフォルトを挿入させます。別の方法として、行内の対応するアイテムを取得する行内
の列のみをリストすることもできます。INSERT
VALUES
動的 SQLを使用して、値だけでなくステートメント自体を操作する必要があります。EXECUTE
「スイングコラム」はfield1
とでfield3
ありlanguage
、残りは定義に従って配線されています。必要に応じて変更します。
私の関数はすべてのケースNULL
で機能します。列のデフォルトの代わりに値を指定することもできます。_cols
これには、挿入する列の情報を提供するパラメーターが必要です。
関連するすべての列が宣言されNOT NULL
ている場合 (明確化されていません)、簡略化できます。NULL
列のデフォルトを取得する必要がある列に渡し、CASE
ステートメントを適応させます。
を省略する_cols
と、すべてのフィールドが挿入されます。_cols
最後のIN
パラメータであり、デフォルト値があるため、いつでも省略できます。
パラメータを値として渡し、動的に構築されたクエリ文字列による SQL インジェクションを防ぐためにUSING
for 句EXECUTE
を使用します。
format()
ステートメントの組み立てを簡素化し、複数の代入を避けるために採用しています。PL/pgSQL の方が安価です。
ヘッダーのパラメーターによって宣言され、自動的に返されるため、関数本体ではDECLARE
_id
andを使用しないでください。_pid
OUT
ステートメントに定数値を直接type
挿入できます。INSERT
この方法では、変数は必要なく、追加の割り当てを保存できます。
PostgreSQL 9.1でテスト済みですが、8.4 以降のすべてのバージョンで動作するはずです - format()
9.1 で導入されたものを除きます。