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

plpgsql関数:ランダムテーブルから作成されたビューから行を返します

    これは次のように機能する可能性があります:

    CREATE OR REPLACE FUNCTION tt_query(orig_name regclass, data_tt timestamp)
      RETURNS SETOF record AS
    $func$
    BEGIN
    
    EXECUTE 'CREATE OR REPLACE TEMP VIEW tmp as 
    select * 
    from  '
    || orig_name 
    || ' where trigger_changed >'
    || quote_literal(data_tt)
    || ' ORDER BY trigger_changed DESC';
    
    -- other work on view tmp
    
    -- return the rows of view temp
    RETURN QUERY
    SELECT * FROM tmp;
    
    END
    $func$  LANGUAGE plpgsql;
    
    • オブジェクト識別子タイプregclass> SQLインジェクションを自動的に回避します。

    • 古い構文varALIAS for $ 1を使用しないでください あなたがする必要がない場合。代わりにパラメータ名を宣言してください。

    • キーワードtempは使用しません それが許可されている場合でも、識別子として。 tmpの使用 代わりに。

    • RETURN QUERYを使用します レコードのセットを返します。これは、 EXECUTEを使用しない静的な呼び出しでもかまいません。 。ただし、匿名のレコードを返しています そしてPostgresは列定義リストを要求します すべての呼び出しで:

    SELECT * FROM tt_query('tbl_name', '2014-02-15 12:00')
    AS f(col1 int, col2 text, ...);

    これはかなり扱いにくいです。

    より良いソリューション

    知っている 戻りタイプ(テーブル名が変更されている場合でも、列のリストが同じタイプを共有している可能性があります)、作成時に宣言します。この関連する質問を検討してください:
    PostgreSQL:エラー:42601:「レコード」を返す関数には列定義リストが必要です

    返品タイプが異なる場合 提供されたテーブル名を使用しても、はるかに優れたソリューションがあります。 SELECT * FROM tblでビューを作成しているので 、テーブル自体のよく知られたタイプを多形 パラメータ:

    CREATE OR REPLACE FUNCTION tt_query(orig_name anyelement, data_tt timestamp)
      RETURNS SETOF anyelement AS
    $func$
    BEGIN
    
    EXECUTE format('CREATE OR REPLACE TEMP VIEW tmp AS
       SELECT * FROM  %s
       WHERE  trigger_changed > %L
       ORDER  BY trigger_changed DESC'
      ,pg_typeof(orig_name)
      ,data_tt);
    
    -- other work on view tmp
    
    -- return the rows of view tmp
    RETURN QUERY
    SELECT * FROM tmp;
    
    END
    $func$  LANGUAGE plpgsql;
    

    簡略化された呼び出し:

    SELECT * FROM tt_query(NULL::tbl_name, '2014-02-15 12:00');
    

    format()<も使用します/ code> 安全でシンプルな文字列連結のために。

    この関連する回答の詳細:
    PL / pgSQL関数をリファクタリングして、さまざまなSELECTクエリの出力を返します




    1. SQLServerからリンクされたOracleServerプロシージャに文字列パラメータを渡す

    2. SQLDeveloperを使用したOracle一括挿入

    3. 1つの表に行がない可能性がある複数の表からの選択によるOracleInsert

    4. 新しい行が挿入されていないのにexecuteUpdateが1を返すのはなぜですか?