Dù bằng cách nào, bạn cũng cần SQL động.
Tên bảng dưới dạng tham số đã cho
CREATE OR REPLACE FUNCTION foo(_number int)
RETURNS TABLE (cpa int, nr text, vym text) AS -- adapt to actual data types!
$func$
BEGIN
RETURN QUERY EXECUTE format(
'SELECT t.cpa, substring(t.ku,'[0-9]+'), p.vym
FROM public."table_data_C" t
LEFT JOIN %s p USING (cpa)'
, 'pa' || _number
);
END
$func$ LANGUAGE plpgsql;
Gọi:
SELECT * FROM foo(456887)
Nói chung, bạn sẽ làm sạch tên bảng với định dạng format ( %I )
để tránh SQL injection. Chỉ với một số nguyên integer
dưới dạng đầu vào động không cần thiết. Thêm chi tiết và liên kết trong câu trả lời có liên quan này:
CHÈN với tên bảng động trong chức năng kích hoạt
Mô hình dữ liệu
Có thể có những lý do chính đáng cho mô hình dữ liệu. Như phân vùng / sharding hoặc các đặc quyền riêng biệt ...
Nếu bạn không có lý do chính đáng như vậy, hãy xem xét việc hợp nhất nhiều bảng có giản đồ giống hệt nhau thành một và thêm number
như cột. Sau đó, bạn không cần SQL động.
Xem xét kế thừa
. Sau đó, bạn có thể thêm một điều kiện trên tableoid
để chỉ truy xuất các hàng từ một bảng con đã cho:
SELECT * FROM parent_table
WHERE tableoid = 'pa456887'::regclass
Tuy nhiên, Hãy lưu ý các giới hạn đối với tính kế thừa. Các câu trả lời liên quan:
- Lấy tên bảng nguồn của một hàng khi truy vấn giá trị gốc mà hàng đó kế thừa
- Chọn (truy xuất) tất cả các bản ghi từ nhiều lược đồ bằng Postgres
Tên của bảng thứ hai tùy thuộc vào giá trị trong bảng thứ nhất
Việc lấy tên của bảng nối từ các giá trị trong bảng đầu tiên sẽ tự động làm phức tạp mọi thứ.
Chỉ dành cho một vài bảng
LEFT JOIN
mỗi trên tableoid
. Chỉ có một kết quả phù hợp cho mỗi hàng, vì vậy hãy sử dụng COALESCE
.
SELECT t.*, t.tbl, COALESCE(p1.vym, p2.vym, p3.vym) AS vym
FROM (
SELECT cpa, ('pa' || substring(ku,'[0-9]+'))::regclass AS tbl
FROM public."table_data_C"
-- WHERE <some condition>
) t
LEFT JOIN pa456887 p1 ON p1.cpa = t.cpa AND p1.tableoid = t.tbl
LEFT JOIN pa456888 p2 ON p2.cpa = t.cpa AND p2.tableoid = t.tbl
LEFT JOIN pa456889 p3 ON p3.cpa = t.cpa AND p3.tableoid = t.tbl
Đối với nhiều bảng
Kết hợp một vòng lặp với các truy vấn động:
CREATE OR REPLACE FUNCTION foo(_number int)
RETURNS TABLE (cpa int, nr text, vym text) AS
$func$
DECLARE
_nr text;
BEGIN
FOR _nr IN
SELECT DISTINCT substring(ku,'[0-9]+')
FROM public."table_data_C"
LOOP
RETURN QUERY EXECUTE format(
'SELECT t.cpa, _nr, p.vym
FROM public."table_data_C" t
LEFT JOIN %I p USING (cpa)
WHERE t.ku LIKE (_nr || '%')'
, 'pa' || _nr
);
END LOOP;
END
$func$ LANGUAGE plpgsql;