一般的なソリューション
set_config()を使用して純粋なSQL関数を作成しました。
このソリューションは、コンマ区切りの文字列での複数のスキーマの設定をサポートしています。デフォルトでは、変更は現在のセッションに適用されます。 「is_local」パラメータをtrueに設定すると、変更は現在のトランザクションにのみ適用されます。 http://www.postgresql.org/docs/9.4/static/functions-admin.html 詳細については。
CREATE OR REPLACE FUNCTION public.set_search_path(path TEXT, is_local BOOLEAN DEFAULT false) RETURNS TEXT AS $$
SELECT set_config('search_path', regexp_replace(path, '[^\w ,]', '', 'g'), is_local);
$$ LANGUAGE sql;
動的SQLを実行していないため、SQLインジェクションの可能性は低くなります。念のため、英数字、スペース、コンマを除くすべての文字を削除して、テキストの単純なサニタイズを追加しました。文字列のエスケープ/引用は簡単ではありませんでしたが、私は専門家ではないので.. =)
不正な形式のパスを設定した場合、フィードバックはないことに注意してください。
テスト用のサンプルコードは次のとおりです。
DROP SCHEMA IF EXISTS testschema CASCADE;
CREATE SCHEMA testschema;
CREATE TABLE testschema.mytable ( id INTEGER );
SELECT set_search_path('testschema, public');
SHOW search_path;
INSERT INTO mytable VALUES(123);
SELECT * FROM mytable;
OPの元のコードに基づくテスト
mytableのスキーマが事前にわからないため、動的SQLを使用する必要があります。一般的な'ish関数を使用する代わりに、set_config-onelinerをget_sections()-関数に埋め込みました。
注: これを機能させるには、set_config()でis_local=falseを設定する必要がありました。これは、関数の実行後も変更されたパスが残ることを意味します。理由はわかりません。
DROP SCHEMA IF EXISTS testschema CASCADE;
CREATE SCHEMA testschema;
SET search_path TO public;
CREATE TABLE testschema.mytable ( id INTEGER, name varchar, type varchar );
INSERT INTO testschema.mytable VALUES (123,'name', 'some-type');
INSERT INTO testschema.mytable VALUES (567,'name2', 'beer');
CREATE OR REPLACE FUNCTION get_sections(schema_name TEXT) RETURNS
TABLE(id integer, name varchar, type varchar) AS $$
BEGIN
PERFORM set_config('search_path', regexp_replace(schema_name||', public', '[^\w ,]', '', 'g'), true);
EXECUTE 'SELECT id, name, type FROM mytable';
END;
$$ LANGUAGE plpgsql;
SET search_path TO public;
SELECT * FROM get_sections('testschema');
SHOW search_path; -- Unfortunately this has modified the search_path for the whole session.