Przekazywanie wielu nazw kolumn jako połączonego ciągu w celu dynamicznego wykonania pilnie wymaga odkażenia. Proponuję VARIADIC
zamiast tego parametr funkcji, z odpowiednio cytowanymi identyfikatorami (za pomocą quote_ident()
w tym przypadku):
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 tutaj
Specyfikator formatu %I
dla format()
zajmuje się singielem identyfikator. Musisz włożyć więcej pracy dla wielu identyfikatory, zwłaszcza dla zmiennej liczby 0-n identyfikatorów. Ta implementacja cytuje każdą nazwę kolumny i dodaje tylko ,
jeśli zostały przekazane jakiekolwiek nazwy kolumn. Więc działa dla każdego możliwego wejścia , nawet brak danych wejściowych. Uwaga VARIADIC cols text[] =NULL
jako ostatni parametr wejściowy z wartością NULL jako domyślną:
Powiązane:
W tym kontekście w nazwach kolumn rozróżniana jest wielkość liter!
Zadzwoń po swój przykład (ważne!):
SELECT select_by_txt(10,32,33,'col1', 'col2');
Alternatywna składnia:
SELECT select_by_txt(10,32,33, VARIADIC '{col1,col2}');
Bardziej odkrywcze wezwanie, z nazwą w trzeciej kolumnie i złośliwą (choć daremną) intencją:
SELECT select_by_txt(10,32,33,'col1', 'col2', $$col3'); DROP TABLE table1;--$$);
O tej dziwnej nazwie trzeciej kolumny i wstrzyknięciu SQL:
O VAIRADIC
parametry:
- Zwróć wiersze pasujące do elementów tablicy wejściowej w funkcji plpgsql
- Przekaż wiele wartości w jednym parametrze
Korzystanie z OUT
parametr dla prostoty. To całkowicie opcjonalne. Zobacz:
Czego bym nie zrobić
Jeśli naprawdę, naprawdę ufasz, że dane wejściowe są odpowiednio sformatowaną listą zawierającą 1 lub więcej prawidłowych nazw kolumn przez cały czas - i zapewniłeś, że ...
możesz uprościć:
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$;
(Jak możesz mieć pewność, że dane wejściowe będą zawsze wiarygodne?)