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

PostgreSQL-結果セットを返すストアドプロシージャに動的SQLを記述します

    改善の余地があります:

    CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
                                                       , ends_with   text = NULL)
      RETURNS SETOF lookups.countries AS
    $func$
    DECLARE
       sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
    BEGIN
       IF ends_with IS NOT NULL THEN
          sql := sql || ' AND country_name <= $2';
       END IF;
    
       RETURN QUERY EXECUTE sql
       USING starts_with, ends_with;
    END
    $func$ LANGUAGE plpgsql;
    -- the rest is default settings
    

    主なポイント

    • PostgreSQL8.4ではUSINGが導入されました EXECUTEの句 、これはいくつかの理由で役立ちます。マニュアルの要約:

      コマンド文字列は、コマンドで$1, $2として参照されるパラメータ値を使用できます。 、など。これらの記号は、USINGで提供される値を参照します。 句。この方法は、データ値をテキストとしてコマンド文字列に挿入するよりも望ましい場合がよくあります。値をテキストに変換して戻すという実行時のオーバーヘッドを回避し、引用符やエスケープの必要がないため、SQLインジェクション攻撃の可能性がはるかに低くなります。

      IOW、quote_literal()でサニタイズした場合でも、パラメータのテキスト表現を使用してクエリ文字列を作成するよりも安全で高速です。 。
      $1, $2に注意してください クエリ文字列で、USINGで指定された値を参照します 条項、ではない 関数パラメータに。

    • SELECT * FROM lookups.countriesを返す間 、 RETURNを簡略化できます 実証されたような宣言:

      RETURNS SETOF lookups.countries
      

      PostgreSQLには、すべてのテーブルに対して自動的に定義された複合型があります。これを使って。その結果、関数はタイプによって異なり、テーブルを変更しようとするとエラーメッセージが表示されます。このような場合は、関数を削除して再作成してください。

      これは望ましい場合と望ましくない場合があります-一般的にはそうです!テーブルを変更する場合は、副作用を認識しておく必要があります。あなたがそれを持っている方法では、あなたの関数は静かに壊れて、次の呼び出しで例外を引き起こします。

    • 明示的なデフォルトを指定した場合 示されているような宣言の2番目のパラメーターについては、ends_withで上限を設定したくない場合に備えて、呼び出しを単純化できます(ただし、そうする必要はありません)。 。

      SELECT * FROM report_get_countries_new('Zaire');
      

      代わりに:

      SELECT * FROM report_get_countries_new('Zaire', NULL);
      

      このコンテキストでは、関数のオーバーロードに注意してください。

    • 言語名を引用しないでください'plpgsql' それが許容されるとしても(今のところ)。識別子です。

    • 宣言時に変数を割り当てることができます。余分なステップを節約できます。

    • パラメータはヘッダーで指定されます。無意味な線を削除します:

       starts_with ALIAS FOR $1;
       ends_with ALIAS FOR $2;
      


    1. Oracle SQLでトップ1を選択し、日付順に並べ替える方法は?

    2. Postgresql SCRAM認証の問題を解決するにはどうすればよいですか?

    3. LOCALTIMESTAMPの例– MySQL

    4. PostgreSQLでデータベースとテーブルを一覧表示する方法