sql >> データベース >  >> RDS >> PostgreSQL

指定されたテーブルの動的な列のセットを返す関数

    単純なケースの解決策

    以下の参照された回答で説明されているように、登録された(行)型を使用できるため、多態性関数の戻り型を暗黙的に宣言できます。

    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)でラップできます。 、jsonbhstorexml

    または 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に置き換えることができます。 列。



    1. SQL Serverでsys.sql_dependenciesを使用しないでください(非推奨)

    2. パラメータがNULLの場合にデフォルト値を列に挿入する

    3. Oracleインデックスを選択して最適化する方法は?

    4. トップ5のMySQLGUIツール(無料および有料)