動的実行のために複数の列名を連結文字列として渡すには、緊急に除染が必要です。 VARIADIC コード>
代わりに、適切に引用された識別子を使用した関数パラメータ( quote_ident()
を使用) この場合):
CREATE OR REPLACE FUNCTION select_by_txt(z int, x int, y int, VARIADIC cols text[] = NULL, OUT res text)
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE format(
$$
SELECT ST_AsMVT(mvtgeom, 'public.select_by_txt')
FROM (
SELECT ST_AsMVTGeom(ST_Transform(t.geom, 3857), bounds.geom) AS geom%s
FROM table1 t
JOIN (SELECT ST_TileEnvelope($1, $2, $3)) AS bounds(geom)
ON ST_Intersects(t.geom, ST_Transform(bounds.geom, 4326))
) mvtgeom
$$, (SELECT ', ' || string_agg(quote_ident (col), ', ') FROM unnest(cols) col)
)
INTO res
USING z, x, y;
END
$func$;
db <> fiddle こちら
フォーマット指定子%I
format()
の場合 シングルを扱います 識別子。 複数の場合はさらに作業を行う必要があります 識別子、特に可変数の0-n識別子の場合。この実装では、すべての列名を引用し、、
のみを追加します 列名が渡された場合。したがって、すべての可能な入力に対して機能します 、入力がまったくない場合でも。 VARIADIC cols text [] =NULL
に注意してください デフォルト値としてNULLを使用する最後の入力パラメーターとして:
関連:
このコンテキストでは、列名で大文字と小文字が区別されます!
あなたの例を求めてください(重要です!):
SELECT select_by_txt(10,32,33,'col1', 'col2');
代替構文:
SELECT select_by_txt(10,32,33, VARIADIC '{col1,col2}');
3番目の列の名前と悪意のある(無駄ではありますが)意図を持った、より明白な呼び出し:
SELECT select_by_txt(10,32,33,'col1', 'col2', $$col3'); DROP TABLE table1;--$$);
その奇妙な3番目の列名とSQLインジェクションについて:
VAIRADIC
について パラメータ:
OUT
の使用 簡単にするためのパラメータ。それは完全にオプションです。参照:
私がしないこと 行う
本当に、入力が常に1つ以上の有効な列名の適切にフォーマットされたリストであると本当に信頼している場合-そしてあなたはそれを主張しました...
あなたはできた 簡素化:
CREATE OR REPLACE FUNCTION select_by_txt(z int, x int, y int, cols text, OUT res text)
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE format(
$$
SELECT ST_AsMVT(mvtgeom, 'public.select_by_txt')
FROM (
SELECT ST_AsMVTGeom(ST_Transform(t.geom, 3857), bounds.geom) AS geom, %s
FROM table1 t
JOIN (SELECT ST_TileEnvelope($1, $2, $3)) AS bounds(geom)
ON ST_Intersects(t.geom, ST_Transform(bounds.geom, 4326))
) mvtgeom
$$, cols
)
INTO res
USING z, x, y;
END
$func$;
(入力が常に信頼できるものになるようにするにはどうすればよいですか?)