PostgreSQLで一時関数を作成するにはどうすればよいですか?


83

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

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

回答:


115

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

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

あなたの接続が固執する限り、固執する機能になります。ドロップコマンドを呼び出す必要はありません。


61

@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');

詳細:


31

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

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

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


4
...ターミナルでのスクリプト作成には便利ですが、「匿名関数」(またはラムダ)のように再度呼び出すことはできないため、DOステートメントは「一時関数」ほど有用ではありません。
ピータークラウス2014年

@PeterKrauss:もう一度呼び出したい場合は、実際の関数を作成する必要があります。
a_horse_with_no_name 2014年

もちろん、私のa_hourse :-)「一時的」を実装するための理論的なパスのみを示していました...これが、主な質問に対するより良い答え(PostgreSQLで可能)がである理由ですpg_temp.foo()。なぜ(!?)今日、2014年、Luaのように単純で高速な例では、SQL DML言語はラムダ関数(!)を提供できないのかわかりません。
ピータークラウス2014年

7
また、DO関数とは異なり、ステートメントは入力パラメーターを持つことができず、結果を返すこともできません。
ダニエルヴェライト2015

2
戻らない場合は「関数」と呼ぶべきでしょうか?
AndreKR 2016年

-4

アドホック手順の場合、カーソルはそれほど悪くありません。ただし、productinoで使用するには非効率的です。

それらを使用すると、データベース内のSQL結果を簡単にループできます。


6
PostgreSQLでカーソルが非効率的であるのはなぜだと思いますか?
フランクハイケンス2011

2
カーソルは、ループ時にデータベース接続を保持します。何百もの長時間実行カーソルがあるWebページは接続を枯渇させ、サイト/データベースをひざまずかせます。
バイロンホイットロック2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.