PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak używać wprowadzania tekstu jako nazw kolumn w funkcji Postgresa?

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:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zapobiec zmienianiu przez PostgreSQL moich ładnie sformatowanych definicji SQL?

  2. Rozp. wsparcie transakcji dla wiosennego zadania wsadowego na poziomie zadania

  3. Jak połączyć kontener aplikacji webowej Docker z kontenerem Docker PostgreSQL?

  4. Postgres:zdefiniować domyślną wartość dla niepowodzeń CAST?

  5. Posortować według kolumny ASC, ale najpierw wartości NULL?