PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm cách nào để sử dụng kiểu nhập văn bản dưới dạng (các) tên cột trong hàm Postgres?

Việc chuyển nhiều tên cột dưới dạng chuỗi được nối để thực thi động đòi hỏi phải khử nhiễm khẩn cấp. Tôi đề xuất một VARIADIC thay vào đó, tham số hàm với số nhận dạng được trích dẫn chính xác (sử dụng quote_ident () trong trường hợp này):

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 tại đây

Bộ định dạng % I cho format () giao dịch với một đơn định danh. Bạn phải thực hiện nhiều công việc hơn cho nhiều số nhận dạng, đặc biệt là đối với một số định danh 0-n thay đổi. Việc triển khai này trích dẫn mọi tên cột và chỉ thêm một , nếu bất kỳ tên cột nào đã được thông qua. Vì vậy, nó hoạt động cho mọi đầu vào có thể , thậm chí không có đầu vào nào cả. Lưu ý VARIADIC cols text [] =NULL làm tham số đầu vào cuối cùng với NULL làm giá trị mặc định:

Có liên quan:

Tên cột phân biệt chữ hoa chữ thường trong ngữ cảnh này!

Gọi cho ví dụ của bạn (quan trọng!):

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

Cú pháp thay thế:

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

Lời gọi tiết lộ hơn, với tên cột thứ ba và mục đích xấu (mặc dù vô ích):

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

Giới thiệu về tên cột thứ ba kỳ lạ đó và chèn SQL:

Giới thiệu về VAIRADIC thông số:

Sử dụng OUT tham số cho đơn giản. Đó là hoàn toàn tùy chọn. Xem:

Điều gì tôi sẽ không làm

Nếu bạn thực sự, hãy thực sự tin tưởng đầu vào là danh sách được định dạng đúng gồm 1 hoặc nhiều tên cột hợp lệ mọi lúc - và bạn đã khẳng định rằng ...

Bạn có thể đơn giản hóa:

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

(Làm thế nào bạn có thể chắc chắn rằng đầu vào sẽ luôn đáng tin cậy?)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hiệu suất quét đống bitmap

  2. Lỗi với auto_increment khi được kết nối với Postgres qua psql và puTTY

  3. Khi nào chúng ta có thể sử dụng số định danh thay cho tên của nó trong PostgreSQL?

  4. Nhận kết quả từ truy vấn trong DO satement

  5. Cách chỉ định danh sách giá trị cho chuỗi postgresql