1. Cursore implicito
È quasi sempre meglio usare il cursore implicito di un FOR
ciclo piuttosto che ricorrere a un cursore esplicito un po' più lento e ingombrante. Ho scritto migliaia di funzioni plpgsql e solo una manciata di volte in cui i cursori espliciti avevano un senso.
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;
A parte:non c'è nulla nella funzione che necessiti di volatilità VOLATILE
. Usa STABLE
.
2. Approccio basato sugli insiemi
È quasi sempre meglio utilizzare un approccio basato sugli insiemi se possibile . Usa RETURN QUERY
per restituire direttamente come impostato da una query.
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. Funzione SQL
Per il caso semplice (probabilmente una semplificazione), potresti anche usare una semplice funzione SQL o anche solo la query:
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;