94

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

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

4

4 に答える 4

136

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

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

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

于 2012-04-02T18:12:34.230 に答える
70

@crowmagnumb の回答のスマート トリックに対するいくつかの追加メモ:

  • Tom Lane によると、トロイの木馬を防ぐために、(デフォルトのように) であっても、関数は常にスキーマ修飾されている必要があります。pg_tempsearch_path
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');

詳細:

于 2015-06-28T02:04:46.340 に答える
31

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

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

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

于 2011-02-14T09:40:41.453 に答える
-6

For ad hock procedures, cursors aren't too bad. They are too inefficient for productino use however.

They will let you easily loop on sql results in the db.

于 2011-02-14T09:41:12.270 に答える