Na verdade, você não está retornando o resultado. Você usaria
RETURN QUERY EXECUTE
por isso. Exemplo:Mas você não precisa de SQL dinâmico aqui para começar ...
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;
Chamada com array real:
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
Ou ligue com lista de itens ("dicionário"):
SELECT * FROM get_items_by_tag('tag1', 'tag2');
Pontos principais
-
UseRETURN QUERY
para realmente retornar as linhas resultantes.
-
Não use SQL dinâmico a menos que você precise. (SemEXECUTE
aqui.)
-
Use umANY
construir em vez deIN
. Por quê?
-
Sugiro umVARIADIC
função por conveniência. Dessa forma, você pode passar um array ou uma lista de itens à sua escolha. Ver:
-
Evite identificadores de maiúsculas e minúsculas no Postgres, se possível.
Não tenho certeza porque você tem
IF array_length(tags, 1) > 0 THEN
, mas provavelmente pode ser substituído por IF tags IS NOT NULL THEN
ou não IF
e continue com IF NOT FOUND THEN
. Mais: