In realtà non stai ritornando il risultato. Dovresti usare RETURN QUERY EXECUTE
per quello. Esempio:
Ma non hai bisogno di SQL dinamico qui per cominciare ...
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;
Chiama con l'array effettivo:
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
Oppure chiama con l'elenco delle voci ("dizionario"):
SELECT * FROM get_items_by_tag('tag1', 'tag2');
Punti principali
-
Usa
RETURN QUERY
per restituire effettivamente le righe risultanti. -
Non utilizzare SQL dinamico a meno che non sia necessario. (Nessun
EXECUTE
qui.) -
Usa un
ANY
costruire invece diIN
. Perché? -
Suggerisco un
VARIADIC
funzione per comodità. In questo modo puoi passare un array o un elenco di elementi a tua scelta. Vedi: -
Se possibile, evita gli identificatori di maiuscole e minuscole in Postgres.
Non sono sicuro del motivo per cui hai IF array_length(tags, 1) > 0 THEN
, ma probabilmente può essere sostituito con IF tags IS NOT NULL THEN
o nessun IF
del tutto e continua con IF NOT FOUND THEN
. Altro: