1. Niejawny kursor
Prawie zawsze lepiej jest użyć niejawnego kursora FOR
pętla niż uciekać się do nieco wolniejszego i nieporęcznego wyraźnego kursora. Napisałem tysiące funkcji plpgsql i tylko garść pełna jawnych kursorów miała sens.
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;
Poza tym:w funkcji nie ma nic, co wymagałoby zmienności VOLATILE
. Użyj STABLE
.
2. Podejście oparte na zbiorach
Prawie zawsze lepiej jest zastosować podejście oparte na zbiorach jeśli to możliwe . Użyj RETURN QUERY
aby powrócić jako zestaw bezpośrednio z zapytania.
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. Funkcja SQL
W prostym przypadku (prawdopodobnie uproszczenie) możesz również użyć prostej funkcji SQL lub nawet samego zapytania:
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;