データベースでループを実行する必要があります。これは1回限りの要件です。関数を実行した後、関数を削除しています。
一時的/使い捨ての機能を作成するための良いアプローチはありますか?
回答:
自分が書いているスクリプトで何度も使用する方法を知る必要がありました。pg_tempスキーマを使用して一時関数を作成できることがわかりました。これは、接続のオンデマンドで作成され、一時テーブルが格納されるスキーマです。接続が閉じられるか期限切れになると、このスキーマは削除されます。このスキーマで関数を作成すると、スキーマが自動的に作成されます。したがって、
create function pg_temp.testfunc() returns text as
$$ select 'hello'::text $$ language sql;
あなたの接続が固執する限り、固執する機能になります。ドロップコマンドを呼び出す必要はありません。
@crowmagnumbの回答のスマートトリックに対するいくつかの追加のメモ:
CREATE FUNCTION pg_temp.f_inc(int)
RETURNS int AS 'SELECT $1 + 1' LANGUAGE sql IMMUTABLE;
SELECT pg_temp.f_inc(42);
f_inc
-----
43
一時スキーマで作成された関数は、同じセッション内でのみ表示されます(一時テーブルと同様)。他のすべてのセッションには表示されません(同じ役割の場合でも)。の後に、同じセッションで別の役割として関数にアクセスできますSET ROLE
。
この「一時」関数に基づいて関数インデックスを作成することもできます。
CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));
これにより、非一時テーブルで一時関数を使用してプレーンインデックスを作成します。このようなインデックスはすべてのセッションに表示されますが、それでも作成中のセッションに対してのみ有効です。クエリプランナーは、式がクエリで繰り返されない機能インデックスを使用しません。まだ少し汚いトリック。セッションが閉じられると、依存オブジェクトとして自動的に削除されます。これはまったく許されるべきではないように感じます...
関数を繰り返し実行する必要があり、必要なのがSQLだけの場合は、代わりにプリペアドステートメントを検討してください。これは、セッションの終了時に終了する一時的なSQL関数のように機能します。ただし、同じことではなく、EXECUTE
別のクエリ内にネストすることなく、で単独で使用することもできます。例:
PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;
コール:
EXECUTE upd_tbl(123, 'foo_name');
詳細:
バージョン9.0を使用している場合は、新しいDOステートメントを使用してこれを行うことができます。
http://www.postgresql.org/docs/current/static/sql-do.html
以前のバージョンでは、関数を作成して呼び出し、再度ドロップする必要があります。
pg_temp.foo()
。なぜ(!?)今日、2014年、Luaのように単純で高速な例では、SQL DML言語はラムダ関数(!)を提供できないのかわかりません。
DO
関数とは異なり、ステートメントは入力パラメーターを持つことができず、結果を返すこともできません。
アドホック手順の場合、カーソルはそれほど悪くありません。ただし、productinoで使用するには非効率的です。
それらを使用すると、データベース内のSQL結果を簡単にループできます。