私は2つの文字列を持っています:
- 「UPP」
- 「ER」
そして、値、たとえば「a」。
UPPER
関数(2つの文字列から合成)を呼び出し、その値をパラメーターとして渡す必要があります。
これどうやってするの?
(実際には、関数のクロス集計を列のカウンターと連結する必要があります。。。。)
私は2つの文字列を持っています:
そして、値、たとえば「a」。
UPPER
関数(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
あります。そうしないと、例外が発生します。