1. Cursor implícito
Casi siempre es mejor usar el cursor implícito de un FOR
bucle que recurrir a un cursor explícito algo más lento y difícil de manejar. He escrito miles de funciones plpgsql y solo un puñado de veces los cursores explícitos tuvieron algún 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;
Aparte:no hay nada en la función que necesite volatilidad VOLATILE
. Usa STABLE
.
2. Enfoque basado en conjuntos
Casi siempre es mejor usar un enfoque basado en conjuntos si es posible . Utilice RETURN QUERY
para devolver como se establece desde una consulta directamente.
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. Función SQL
Para el caso simple (probablemente una simplificación), también puede usar una función SQL simple o incluso solo la 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;