0

私は2つの文字列を持っています:

  • 「UPP」
  • 「ER」

そして、値、たとえば「a」。

UPPER関数(2つの文字列から合成)を呼び出し、その値をパラメーターとして渡す必要があります。
これどうやってするの?

(実際には、関数のクロス集計を列のカウンターと連結する必要があります。。。。)

4

1 に答える 1

2

動的 SQL を使用する関数のスタブは、次のようになります。

CREATE OR REPLACE FUNCTION f_exec(text, text, text, OUT result text)
  RETURNS text AS
$func$
BEGIN
    EXECUTE 'SELECT ' || $1  || $2 || '($1)' -- last $1 not referring func param
    INTO   result
    USING  $3;
END
$func$ LANGUAGE plpgsql;

電話:

SELECT f_exec('up', 'per', 'a')

混乱しないでください。$1内部に独自のスコープがあり、外側の関数パラメーターではなく、句EXECUTEによって渡されたパラメーターを参照します。USING

この関連する回答またはマニュアルの動的コマンドの実行の章の詳細な背景。

警告

これにより、SQL インジェクションが可能になります。dba.SE に関するこの関連する質問
の下のアドバイスと、マニュアルの「関数の安全な記述の章をお読みください。SECURITY DEFINER

この特殊なケースでSQLi を回避する賢明な方法があります。

CREATE OR REPLACE FUNCTION f_exec(
   func1 text
  ,func2 text
  ,param text
  ,OUT result text) AS
$func$
DECLARE
   funcname text := (func1 || func2)::regproc;
BEGIN
   EXECUTE 'SELECT ' || funcname || '($1)::text'
   INTO   result
   USING  param;
END
$func$ LANGUAGE plpgsql;

オブジェクト識別子型regprocへのキャストは、$1およびを介して有効な関数名以外を注入しようとするすべての試みを効果的に排除します$2。このUSING句は、$3( param) を介してコードを挿入しようとする試みをすでに無力化しています。

また:

  • 混乱を避けるために、パラメーター名を使用してください。
  • パラメータがそれを処理するRETURNINGため、関数定義から句を省略します。OUT
  • text関数の実際の戻り値の型がわからず、Postgres のすべてのデータ型を にキャストできるため、関数の結果をにキャストしtextます。
    関数は、タイプの単一のINパラメーターを受け入れる必要がtextあります。そうしないと、例外が発生します。
于 2013-02-05T18:08:46.910 に答える