sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan bruger man tekstinput som kolonnenavn(e) i en Postgres-funktion?

At sende flere kolonnenavne som sammenkædet streng til dynamisk udførelse kræver akut dekontaminering. Jeg foreslår en VARIADIC funktionsparameter i stedet med korrekt anførte identifikatorer (ved hjælp af quote_ident() i dette tilfælde):

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 her

Formatspecifikationen %I for format() omhandler en enkelt identifikator. Du skal lægge mere arbejde for flere identifikatorer, især for et variabelt antal 0-n identifikatorer. Denne implementering citerer hvert enkelt kolonnenavn og tilføjer kun en , hvis nogen kolonnenavne er blevet bestået. Så det virker til alle mulige input , selv ingen input overhovedet. Bemærk VARIADIC cols text[] =NULL som sidste inputparameter med NULL som standardværdi:

Relateret:

Kolonnenavne skelner mellem store og små bogstaver i denne sammenhæng!

Ring for dit eksempel (vigtigt!):

SELECT select_by_txt(10,32,33,'col1', 'col2');

Alternativ syntaks:

SELECT select_by_txt(10,32,33, VARIADIC '{col1,col2}');

Mere afslørende opkald med et tredje kolonnenavn og ondsindet (omend forgæves) hensigt:

SELECT select_by_txt(10,32,33,'col1', 'col2', $$col3'); DROP TABLE table1;--$$);

Om det ulige tredje kolonnenavn og SQL-injektion:

Om VAIRADIC parametre:

Brug af en OUT parameter for enkelhedens skyld. Det er helt valgfrit. Se:

Hvad jeg ikke ville gør

Hvis du virkelig, virkelig stoler på, at inputtet er en korrekt formateret liste med 1 eller flere gyldige kolonnenavne til enhver tid - og du hævdede, at ...

Du kunne forenkle:

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$;

(Hvordan kan du være så sikker på, at input altid vil være pålideligt?)



  1. PHP MYSQL SET giver fejl i while loop

  2. INSERT Statement i PL/SQL mislykkes i Oracle-databasen

  3. MySql FEJL 1045 (28000):Adgang nægtet for brugeren 'root'@'localhost' (ved hjælp af adgangskode:NEJ)

  4. Forøg først tæller og skinner ved hjælp af postgreSQL mærkelig adfærd