Ve skutečnosti se nevracíte výsledek. Použili byste RETURN QUERY EXECUTE
pro to. Příklad:
Ale zde nepotřebujete dynamické SQL, abyste mohli začít s ...
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;
Volání se skutečným polem:
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
Nebo zavolejte se seznamem položek („slovník“):
SELECT * FROM get_items_by_tag('tag1', 'tag2');
Hlavní body
-
Použijte
RETURN QUERY
skutečně vrátit výsledné řádky. -
Nepoužívejte dynamické SQL, pokud to nepotřebujete. (Žádné
EXECUTE
zde.) -
Použijte
ANY
konstrukt místoIN
. Proč? -
Navrhuji
VARIADIC
funkce pro pohodlí. Tímto způsobem můžete předat pole nebo seznam položek podle svého výběru. Viz: -
Pokud je to možné, vyhněte se v Postgresu identifikátorům se smíšenou velikostí písmen.
Nejste si jisti, proč máte IF array_length(tags, 1) > 0 THEN
, ale pravděpodobně jej lze nahradit IF tags IS NOT NULL THEN
nebo žádné IF
vůbec a pokračujte s IF NOT FOUND THEN
. Více: