sql >> Databáze >  >> RDS >> PostgreSQL

Jak používat textový vstup jako názvy sloupců ve funkci Postgres?

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:

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ý?)



  1. Jak přiřadit uživatele k více schématu databáze?

  2. Vyberte 10 nejlepších záznamů pro každou kategorii v MySQL

  3. MySQL:Jak zabránit tomu, aby uživatel dokonce viděl, že mám jiné DB, a udělit vybraný přístup k jednomu pohledu na jedné DB?

  4. Přidání do stejného pole se dvěma různými smyčkami foreach PHP/SQL