Předávání více názvů sloupců jako zřetězeného řetězce pro dynamické provádění naléhavě vyžaduje dekontaminaci. Navrhuji VARIADIC
funkční parametr se správně uvozenými identifikátory (pomocí quote_ident()
v tomto případě):
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 zde
Specifikátor formátu %I
pro format()
se zabývá jediným identifikátor. Musíte vynaložit více práce pro více identifikátory, zejména pro proměnný počet 0-n identifikátorů. Tato implementace uvádí každý název sloupce a přidává pouze ,
pokud byly předány nějaké názvy sloupců. Takže to funguje pro každý možný vstup , dokonce žádný vstup. Poznámka VARIADIC cols text[] =NULL
jako poslední vstupní parametr s výchozí hodnotou NULL:
Související:
V názvech sloupců se v tomto kontextu rozlišují velká a malá písmena!
Zavolejte si o svůj příklad (důležité!):
SELECT select_by_txt(10,32,33,'col1', 'col2');
Alternativní syntaxe:
SELECT select_by_txt(10,32,33, VARIADIC '{col1,col2}');
Odhalující hovor s názvem ve třetím sloupci a se zlým (i když marným) záměrem:
SELECT select_by_txt(10,32,33,'col1', 'col2', $$col3'); DROP TABLE table1;--$$);
O tom zvláštním názvu třetího sloupce a vložení SQL:
O aplikaci VAIRADIC
parametry:
- Vrátí řádky odpovídající prvkům vstupního pole ve funkci plpgsql
- Předejte více hodnot v jednom parametru
Pomocí OUT
parametr pro jednoduchost. To je zcela volitelné. Viz:
Co bych ne udělat
Pokud opravdu, opravdu důvěřujete tomu, že vstup je vždy správně naformátovaný seznam 1 nebo více platných názvů sloupců – a tvrdili jste, že ...
Mohli byste zjednodušit:
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 si můžete být tak jisti, že vstup bude vždy spolehlivý?)