Giải pháp cho trường hợp đơn giản
Như được giải thích trong các câu trả lời được tham khảo bên dưới, bạn có thể sử dụng các kiểu (hàng) đã đăng ký và do đó khai báo ngầm định kiểu trả về của một hàm đa hình:
CREATE OR REPLACE FUNCTION public.get_table(_tbl_type anyelement)
RETURNS SETOF anyelement AS
$func$
BEGIN
RETURN QUERY EXECUTE format('TABLE %s', pg_typeof(_tbl_type));
END
$func$ LANGUAGE plpgsql;
Gọi:
SELECT * FROM public.get_table(NULL::public.users); -- note the syntax!
Trả về bảng hoàn chỉnh (với tất cả các cột người dùng).
Chờ đã! Làm thế nào?
Giải thích chi tiết trong câu trả lời liên quan này, chương "Các loại bảng hoàn chỉnh khác nhau" :
- Cấu trúc lại một hàm PL / pgSQL để trả về kết quả đầu ra của các truy vấn SELECT khác nhau
TABLE foo
chỉ là viết tắt của SELECT * FROM foo
:
- Có phím tắt nào cho SELECT * FROM không?
2 các bước cho kiểu trả lại hoàn toàn động
Nhưng những gì bạn đang cố gắng làm là hoàn toàn không thể trong một single Lệnh SQL.
Tôi muốn chuyển
schema_name
vàtable_name
làm tham số cho chức năng và nhận danh sách bản ghi, theocolumn_visible
trường trongpublic.fields
bảng.
Không có cách nào trực tiếp để trả về lựa chọn cột tùy ý (kiểu trả về không được biết tại thời điểm gọi) từ một hàm - hoặc bất kỳ Lệnh SQL. SQL yêu cầu biết số lượng, tên và loại cột kết quả tại thời điểm gọi. Xem thêm trong chương 2 của câu trả lời liên quan này:
- Làm cách nào để tạo CROSS JOIN xoay quanh trong đó định nghĩa bảng kết quả là không xác định?
Có nhiều cách giải quyết khác nhau . Bạn có thể bọc kết quả bằng một trong các loại tài liệu chuẩn (json
, jsonb
, hstore
, xml
).
Hoặc bạn tạo truy vấn bằng một lệnh gọi hàm và thực thi kết quả với lệnh tiếp theo:
CREATE OR REPLACE FUNCTION public.generate_get_table(_schema_name text, _table_name text)
RETURNS text AS
$func$
SELECT format('SELECT %s FROM %I.%I'
, string_agg(quote_ident(column_name), ', ')
, schema_name
, table_name)
FROM fields
WHERE column_visible
AND schema_name = _schema_name
AND table_name = _table_name
GROUP BY schema_name, table_name
ORDER BY schema_name, table_name;
$func$ LANGUAGE sql;
Gọi:
SELECT public.generate_get_table('public', 'users');
Điều này tạo ra một truy vấn có dạng:
SELECT usr_id, usr FROM public.users;
Thực hiện nó ở bước thứ 2. (Bạn có thể muốn thêm số cột và thứ tự cột.)
Hoặc thêm \gexec
trong psql để thực thi giá trị trả về ngay lập tức. Xem:
Cách buộc đánh giá truy vấn con trước khi tham gia / đẩy xuống máy chủ nước ngoài
Hãy chắc chắn để bảo vệ khỏi việc đưa vào SQL:
- CHÈN với tên bảng động trong chức năng kích hoạt
- Xác định tên bảng và cột làm đối số trong hàm plpgsql?
varchar(100)
không có nhiều ý nghĩa đối với số nhận dạng, được giới hạn trong 63 ký tự trong Postgres tiêu chuẩn:
- Các ký tự tối đa trong nhãn (tên bảng, cột, v.v.)
Nếu bạn hiểu cách định danh đối tượng, loại regclass
hoạt động, bạn có thể thay thế lược đồ và tên bảng bằng một regclass
singe cột.