Bạn không thực sự quay trở lại kết quả. Bạn sẽ sử dụng RETURN QUERY EXECUTE
cho điều đó. Ví dụ:
Nhưng bạn không cần SQL động ở đây để bắt đầu bằng ...
CREATE OR REPLACE FUNCTION get_items_by_tag(VARIADIC tags text[])
RETURNS TABLE (id int, title text, tag text[]) AS
$func$
BEGIN
IF array_length(tags, 1) > 0 THEN
-- NO need for EXECUTE
RETURN QUERY
SELECT d.id, d.title, array_agg(t.title)
FROM items d
JOIN item_tags dt ON dt.item_id = d.id
JOIN tags t ON t.id = dt.tag_id
AND t.title = ANY ($1) -- use ANY construct
GROUP BY d.id; -- PK covers whole table
-- array_to_string(tags, ',') -- no need to convert array with ANY
-- ELSE ...
END IF;
END
$func$ LANGUAGE plpgsql;
Gọi với mảng thực tế:
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
Hoặc gọi kèm theo danh sách các mục ("từ điển"):
SELECT * FROM get_items_by_tag('tag1', 'tag2');
Những điểm chính
-
Sử dụng
RETURN QUERY
để thực sự trả về các hàng kết quả. -
Không sử dụng SQL động trừ khi bạn cần. (Không
EXECUTE
tại đây.) -
Sử dụng
ANY
cấu trúc thay vìIN
. Tại sao? -
Tôi đề xuất một
VARIADIC
chức năng để thuận tiện. Bằng cách này, bạn có thể chuyển một mảng hoặc danh sách các mục theo lựa chọn của bạn. Xem: -
Tránh các mã nhận dạng có chữ hoa và chữ thường trong Postgres nếu có thể.
Không chắc tại sao bạn có IF array_length(tags, 1) > 0 THEN
, nhưng có thể được thay thế bằng thẻ IF tags IS NOT NULL THEN
hoặc không có IF
hoàn toàn và theo dõi với IF NOT FOUND THEN
. Thêm: