web-dev-qa-db-ja.com

PostgreSQLで一時関数を作成する方法は?

データベースでループを実行する必要があります。これは1回限りの要件です。関数を実行した後、現在関数を削除しています。

一時的/使い捨ての機能を作成するための良いアプローチはありますか?

60
Anand

私が書いていたスクリプトで何度も使用する方法を知る必要がありました。 pg_tempスキーマを使用して一時関数を作成できることがわかりました。これは、接続のオンデマンドで作成されるスキーマであり、一時テーブルが格納される場所です。接続が閉じられるか期限が切れると、このスキーマは削除されます。このスキーマで関数を作成すると、スキーマが自動的に作成されます。したがって、

create function pg_temp.testfunc() returns text as 
$$ select 'hello'::text $$ language sql;

接続が維持される限り、維持される機能になります。ドロップコマンドを呼び出す必要はありません。

93
crowmagnumb

@ crowmagnumbの答えのスマートトリック :へのいくつかの追加メモ

  • 関数は、pg_tempsearch_path(デフォルトのように)にある場合でも、常にschema-qualifiedでなければなりません)、 トムレーンによる トロイの木馬を防ぐため:
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の後に、同じセッションで別のロールとして関数にアクセスできましたcould

  • この「temp」関数に基づいて機能インデックスを作成することもできます。

    CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));
    

    これにより、非一時テーブルで一時関数を使用してプレーンインデックスを作成します。このようなインデックスはすべてのセッションに表示されますが、作成セッションに対してのみ有効です。クエリプランナーは、クエリ内で式が繰り返されない機能インデックスを使用しません。まだ少し汚いトリックです。セッションが終了すると、依存オブジェクトとして自動的に削除されます。これはまったく許可されるべきではないと感じています...


関数を繰り返し実行する必要があり、必要なものがSQLだけである場合は、代わりに prepared statement を検討してください。これは、セッションの終了時に死ぬ一時SQL関数のように機能します。ただし、sameのことではなく、EXECUTEでのみ単独で使用でき、別のクエリ内にネストされません。例:

PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;

コール:

EXECUTE upd_tbl(123, 'foo_name');

詳細:

48

バージョン9.0を使用している場合は、新しいDOステートメントでこれを行うことができます。

http://www.postgresql.org/docs/current/static/sql-do.html

以前のバージョンでは、関数を作成して呼び出し、再度ドロップする必要があります。

27