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ố:
- Trả về các hàng phù hợp với các phần tử của mảng đầu vào trong hàm plpgsql
- Chuyển nhiều giá trị trong một tham 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?)