En realidad no regresarás el resultado. Usarías RETURN QUERY EXECUTE
para eso. Ejemplo:
Pero no necesita SQL dinámico aquí para comenzar con ...
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;
Llamada con matriz real:
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
O llame con la lista de artículos ("diccionario"):
SELECT * FROM get_items_by_tag('tag1', 'tag2');
Puntos principales
-
Utilice
RETURN QUERY
para devolver las filas resultantes. -
No utilice SQL dinámico a menos que lo necesite. (Sin
EXECUTE
aquí.) -
Usa un
ANY
construir en lugar deIN
. ¿Por qué? -
Sugiero un
VARIADIC
función para mayor comodidad. De esta manera, puede pasar una matriz o una lista de elementos a su elección. Ver: -
Evite los identificadores de mayúsculas y minúsculas en Postgres si es posible.
No estoy seguro de por qué tienes IF array_length(tags, 1) > 0 THEN
, pero probablemente se pueda reemplazar con IF tags IS NOT NULL THEN
o sin IF
en absoluto y haga un seguimiento con IF NOT FOUND THEN
. Más: