1. Cursor implícito
É quase sempre melhor usar o cursor implícito de um
FOR
laço do que recorrer a um cursor explícito um pouco mais lento e pesado. Eu escrevi milhares de funções plpgsql e apenas uma mão cheia de vezes que os cursores explícitos faziam algum sentido. CREATE OR REPLACE FUNCTION avoidable_states()
RETURNS SETOF varchar AS
$func$
DECLARE
rec record;
BEGIN
FOR rec IN
SELECT *
FROM address ad
JOIN city ct USING (city_id)
LOOP
IF rec.city LIKE '%hi%' THEN
RETURN NEXT rec.city;
END IF;
END LOOP;
END
$func$ LANGUAGE plpgsql STABLE;
Além disso:não há nada na função que precise de volatilidade
VOLATILE
. Use STABLE
. 2. Abordagem baseada em conjuntos
É quase sempre melhor usar uma abordagem baseada em conjuntos se possível . Use
RETURN QUERY
para retornar como definido de uma consulta diretamente. CREATE OR REPLACE FUNCTION avoidable_states()
RETURNS SETOF varchar AS
$func$
BEGIN
RETURN QUERY
SELECT ct.city
FROM address ad
JOIN city ct USING (city_id)
WHERE ct.city LIKE '%hi%';
END
$func$ LANGUAGE plpgsql STABLE;
3. Função SQL
Para o caso simples (provavelmente uma simplificação), você também pode usar uma função SQL simples ou mesmo apenas a consulta:
CREATE OR REPLACE FUNCTION avoidable_states()
RETURNS SETOF varchar AS
$func$
SELECT ct.city
FROM address ad
JOIN city ct USING (city_id)
WHERE ct.city LIKE '%hi%';
$func$ LANGUAGE sql STABLE;