Vous n'êtes pas réellement de retour le résultat. Vous utiliseriez RETURN QUERY EXECUTE
pour ça. Exemple :
Mais vous n'avez pas besoin de SQL dynamique ici pour commencer...
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;
Appel avec le tableau réel :
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
Ou appelez avec une liste d'éléments ("dictionnaire") :
SELECT * FROM get_items_by_tag('tag1', 'tag2');
Points majeurs
-
Utilisez
RETURN QUERY
pour renvoyer réellement les lignes résultantes. -
N'utilisez pas SQL dynamique sauf si vous en avez besoin. (Pas de
EXECUTE
ici.) -
Utilisez un
ANY
construire au lieu deIN
. Pourquoi ? -
Je propose un
VARIADIC
fonction pour plus de commodité. De cette façon, vous pouvez passer un tableau ou une liste d'éléments à votre choix. Voir : -
Évitez les identifiants à casse mixte dans Postgres si possible.
Vous ne savez pas pourquoi vous avez IF array_length(tags, 1) > 0 THEN
, mais peut probablement être remplacé par IF tags IS NOT NULL THEN
ou pas de IF
du tout et faites un suivi avec IF NOT FOUND THEN
. Plus :