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

PostgreSQL関数からSETOF行を返します

    サニタイズ機能

    現在お持ちのものは、次のように簡略化/サニタイズできます:

    CREATE OR REPLACE FUNCTION func_a (username text = '', databaseobject text = '')
      RETURNS ????
      LANGUAGE plpgsql AS
    $func$
    BEGIN
       RETURN QUERY EXECUTE
       format ('SELECT * FROM %s v1 LEFT JOIN %I v2 USING (id)'
             , CASE WHEN username = '*' THEN 'view1' ELSE 'view3' END
             , databaseobject);
    END
    $func$;
    

    BEGIN ... ENDの追加インスタンスのみが必要です 関数本体で、独自のスコープで個別のコードブロックを開始します。これは、ほとんど必要ありません。

    標準のSQL連結演算子は||です。 。 + 以前のベンダーの「創造的な」追加です。

    キャメルケースの識別子は、二重引用符で囲まない限り使用しないでください。まったく使用しないでください。参照:

    • PostgreSQLの列名では大文字と小文字が区別されますか?

    varchar(4000) また、SQLServerの特定の制限に合わせて調整されています。 Postgresでは特に重要ではありません。 varchar(4000)のみを使用してください 実際に4000文字の制限が必要な場合。 textを使用します -変数がまったく必要ないことを除いて ここでは、関数を単純化した後。

    format()を使用したことがない場合 、まだ、ここのマニュアルを参照してください。

    リターンタイプ

    さて、実際の質問です。SQLでは遅くとも呼び出し時に宣言する必要があるため、動的クエリの戻り型は扱いにくい場合があります。データベースにすでに列定義リストと一致するテーブル、ビュー、または複合型がある場合は、次のように使用できます。

    CREATE FUNCTION foo()
      RETURNS SETOF my_view AS
    ...
    

    それ以外の場合は、(最も単純な)RETURNS TABLEを使用せずに列定義リストをスペルします。 :

    CREATE FUNCTION foo()
      RETURNS TABLE (col1 int, col2 text, ...) AS
    ...
    

    行の種類を増やしていく場合は、匿名のレコードを返すことができます:

    CREATE FUNCTION foo()
      RETURNS SETOF record AS
    ...
    

    ただし、呼び出しごとに列定義リストを提供する必要があるため、これを使用することはほとんどありません。

    SELECT *は使用しません そもそも。列の明確なリストを使用して、戻り値を返し、それに応じて戻り値のタイプを宣言します。

    CREATE OR REPLACE FUNCTION func_a(username text = '', databaseobject text = '')
      RETURNS TABLE(col1 int, col2 text, col3 date)
      LANGUAGE plpgsql AS
    $func$
    BEGIN
       RETURN QUERY EXECUTE
       format ($f$SELECT v1.col1, v1.col2, v2.col3
                  FROM %s v1 LEFT JOIN %I v2 USING (id)$f$
             , CASE WHEN username = '*' THEN 'view1' ELSE 'view3' END
             , databaseobject);
    END
    $func$;
    

    完全に動的なクエリの場合は、関数を使用するのではなく、最初にクライアントでクエリを作成することを検討してください。

    最初に基本を理解する必要があります:

    • PL / pgSQL関数をリファクタリングして、さまざまなSELECTクエリの出力を返します
    • PostgresマニュアルのPL/pgSQL

    次に、ポリモーフィックタイプを使用したより高度なオプションがあります。これにより、呼び出し時にリターンタイプを渡すことができます。詳細については、次の章をご覧ください:

    • PL / pgSQL関数をリファクタリングして、さまざまなSELECTクエリの出力を返します



    1. MariaDBJavaコネクタドライバーのパフォーマンス

    2. 長い単一のSQLiteOpenHelperを、テーブルごとに1つずつ、複数のクラスに分割するにはどうすればよいですか。

    3. PostgreSQL:psqlコマンドラインユーティリティを使用する場合のWindowsでのエンコーディングの問題

    4. MySQLでのLOCATE()関数のしくみ