Вие всъщност не се връщате резултатът. Ще използвате RETURN QUERY EXECUTE
за това. Пример:
Но тук нямате нужда от динамичен SQL, за да започнете с ...
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;
Извикване с действителен масив:
SELECT * FROM get_items_by_tag(VARIADIC '{tag1,tag2}'::text[]);
Или се обадете със списък с елементи ("речник"):
SELECT * FROM get_items_by_tag('tag1', 'tag2');
Основни точки
-
Използвайте
RETURN QUERY
за действително връщане на получените редове. -
Не използвайте динамичен SQL, освен ако не ви е необходим. (Няма
EXECUTE
тук.) -
Използвайте
ANY
конструкция вместоIN
. Защо? -
Предлагам
VARIADIC
функция за удобство. По този начин можете да подадете масив или списък с елементи по ваш избор. Вижте: -
Ако е възможно, избягвайте идентификатори със смесен регистър в Postgres.
Не съм сигурен защо имате IF array_length(tags, 1) > 0 THEN
, но вероятно може да се замени с IF tags IS NOT NULL THEN
или без IF
изобщо и последвайте с IF NOT FOUND THEN
. Още: