単純なケースの解決策
以下の参照された回答で説明されているように、登録された(行)型を使用できるため、多態性関数の戻り型を暗黙的に宣言できます。
CREATE OR REPLACE FUNCTION public.get_table(_tbl_type anyelement)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE format('TABLE %s', pg_typeof(_tbl_type));
END
$func$ LANGUAGE plpgsql;
電話:
SELECT * FROM public.get_table(NULL::public.users); -- note the syntax!
完全なテーブル(すべてのユーザー列を含む)を返します。
待って!どうやって?
この関連する回答の詳細な説明、「さまざまな完全なテーブルタイプ」の章 :
- PL / pgSQL関数をリファクタリングして、さまざまなSELECTクエリの出力を返します
TABLE foo
SELECT * FROM foo
の略です :
- SELECT * FROMのショートカットはありますか?
2 完全に動的なリターンタイプの手順
しかし、あなたがやろうとしていることは厳密に不可能です シングル SQLコマンド。
schema_name
を渡したい およびtable_name
column_visible
に従って、機能してレコードリストを取得するためのパラメータとしてpublic.fields
のフィールド テーブル。
関数から任意の列の選択(呼び出し時に不明な戻りタイプ)を返す直接的な方法はありません-または any SQLコマンド。 SQLは、呼び出し時に結果の列の数、名前、およびタイプを知ることを要求します。この関連する回答の第2章の詳細:
- 結果のテーブル定義が不明なピボットCROSSJOINを生成するにはどうすればよいですか?
さまざまな回避策があります 。結果を標準のドキュメントタイプの1つ(json
)でラップできます。 、jsonb
、hstore
、xml
。
または 1つの関数呼び出しでクエリを生成し、次の関数呼び出しで結果を実行します:
CREATE OR REPLACE FUNCTION public.generate_get_table(_schema_name text, _table_name text)
RETURNS text AS
$func$
SELECT format('SELECT %s FROM %I.%I'
, string_agg(quote_ident(column_name), ', ')
, schema_name
, table_name)
FROM fields
WHERE column_visible
AND schema_name = _schema_name
AND table_name = _table_name
GROUP BY schema_name, table_name
ORDER BY schema_name, table_name;
$func$ LANGUAGE sql;
電話:
SELECT public.generate_get_table('public', 'users');
これにより、次の形式のクエリが作成されます:
SELECT usr_id, usr FROM public.users;
2番目のステップで実行します。 (列番号と順序列を追加することをお勧めします。)
または\gexec
を追加します psqlで、戻り値をすぐに実行します。参照:
外部サーバーに参加/プッシュダウンする前にサブクエリの評価を強制する方法
SQLインジェクションから確実に防御してください:
- トリガー関数に動的テーブル名を指定してINSERT
- plpgsql関数の引数としてテーブル名と列名を定義しますか?
varchar(100)
標準のPostgresでは63文字に制限されている識別子にはあまり意味がありません:
- ラベル(テーブル名、列など)の最大文字数
オブジェクト識別子のタイプがregclass
である方法を理解している場合 動作します。スキーマとテーブル名を単一のregclass
に置き換えることができます。 列。