W rzeczywistości nie powracasz wynik. Użyjesz RETURN QUERY EXECUTE
za to. Przykład:
Ale na początek nie potrzebujesz dynamicznego SQL-a...
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;
Zadzwoń z rzeczywistą tablicą:
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
Lub zadzwoń z listą pozycji ("słownik"):
SELECT * FROM get_items_by_tag('tag1', 'tag2');
Główne punkty
-
Użyj
RETURN QUERY
aby faktycznie zwrócić wynikowe wiersze. -
Nie używaj dynamicznego SQL, chyba że jest to potrzebne. (Nie
EXECUTE
tutaj.) -
Użyj
ANY
konstrukcja zamiastIN
. Dlaczego? -
Proponuję
VARIADIC
funkcja dla wygody. W ten sposób możesz przekazać dowolną tablicę lub listę elementów. Zobacz: -
Jeśli to możliwe, unikaj w Postgresie identyfikatorów składających się z różnych liter.
Nie wiem, dlaczego masz IF array_length(tags, 1) > 0 THEN
, ale prawdopodobnie można je zastąpić tagami IF tags IS NOT NULL THEN
lub nie IF
w ogóle i kontynuuj z IF NOT FOUND THEN
. Więcej: