PostgreSQLクエリで名前付き定数を定義する方法はありますか?例えば:
MY_ID = 5;
SELECT * FROM users WHERE id = MY_ID;
PostgreSQLクエリで名前付き定数を定義する方法はありますか?例えば:
MY_ID = 5;
SELECT * FROM users WHERE id = MY_ID;
この質問は以前にもありました ( How do you use script variables in PostgreSQL? )。ただし、クエリに時々使用するトリックがあります。
with const as (
select 1 as val
)
select . . .
from const cross join
<more tables>
つまり、定数が定義されている const という CTE を定義します。次に、これを任意のレベルで何度でもクエリにクロス結合できます。これは、日付を扱っていて、多くのサブクエリで日付定数を処理する必要がある場合に特に便利です。
PostgreSQL には、MySQL や Oracle のような (グローバル) 変数を定義する方法が組み込まれていません。( 「カスタマイズされたオプション」を使用した限定的な回避策があります)。あなたが正確に望むものに応じて、他の方法があります:
@Gordon already providedのように、 CTEのクエリの先頭に値を指定できます。
そのための簡単なIMMUTABLE
関数を作成できます。
CREATE FUNCTION public.f_myid()
RETURNS int LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
'SELECT 5';
(並列安全設定は、Postgres 9.6 以降にのみ適用されます。)
現在のユーザーに表示されるスキーマに存在する必要があります。つまり、それぞれのsearch_path
. public
デフォルトでは schema と同様です。セキュリティが問題になる場合は、それが の最初のスキーマであることを確認するかsearch_path
、呼び出しでスキーマ修飾します。
SELECT public.f_myid();
データベース内のすべてのユーザー ( schema へのアクセスが許可されているpublic
) に表示されます。
CREATE TEMP TABLE val (val_id int PRIMARY KEY, val text);
INSERT INTO val(val_id, val) VALUES
( 1, 'foo')
, ( 2, 'bar')
, (317, 'baz');
CREATE FUNCTION f_val(_id int)
RETURNS text LANGUAGE sql STABLE PARALLEL RESTRICTED AS
'SELECT val FROM val WHERE val_id = $1';
SELECT f_val(2); -- returns 'baz'
plpgsql は作成時にテーブルの存在をチェックするため、関数を作成する前に (一時) テーブルを作成する必要がありますval
。関数が存続している間に一時テーブルがセッションの最後に削除された場合でもです。呼び出し時に基になるテーブルが見つからない場合、関数は例外を発生させます。
search_path
一時オブジェクトの現在のスキーマは、明示的に指示されていない限り、デフォルトで残りのスキーマよりも優先されます。から一時スキーマを除外することはできませんsearch_path
が、他のスキーマを最初に置くことはできます。
夜の邪悪な生き物 (必要な特権を持つ) は、 をいじくり回してsearch_path
、同じ名前の別のオブジェクトを前に置く可能性があります。
CREATE TABLE myschema.val (val_id int PRIMARY KEY, val text);
INSERT INTO val(val_id, val) VALUES (2, 'wrong');
SET search_path = myschema, pg_temp;
SELECT f_val(2); -- returns 'wrong'
特権ユーザーのみがグローバル設定を変更できるため、それほど脅威ではありません。他のユーザーは、自分のセッションに対してのみ実行できます。を使用した関数の作成SECURITY DEFINER
に関するマニュアルの関連する章を検討してください。
ハードワイヤード スキーマは通常、よりシンプルで高速です。
CREATE FUNCTION f_val(_id int)
RETURNS text LANGUAGE sql STABLE PARALLEL RESTRICTED AS
'SELECT val FROM pg_temp.val WHERE val_id = $1';
より多くのオプションを含む関連する回答:
Gordon と Erwin が既に述べた適切なオプション (一時テーブル、定数を返す関数、CTE など) に加えて、PostgreSQL の GUC メカニズムを (ab) 使用して、グローバル、セッション、およびトランザクション レベルの変数を作成することもできます。
アプローチの詳細を示すこの以前の投稿を参照してください。
これを一般的に使用することはお勧めしませんが、リンクされた質問で言及されているような狭いケースでは役立つ可能性があります.