複数のテーブルを結合するクエリにカーソルを使用しようとしています。 Oracleにはカーソルベースのレコードがあることがわかりました。 Postgresで同じことをしようとすると、エラーが発生します。 Postgresでも同じことができますか?
CREATE OR REPLACE FUNCTION avoidable_states()
RETURNS SETOF varchar AS
$BODY$
DECLARE
xyz CURSOR FOR select * from address ad
join city ct on ad.city_id = ct.city_id;
xyz_row RECORD;
BEGIN
open xyz;
LOOP
fetch xyz into xyz_row;
exit when xyz_row = null;
if xyz_row.city like '%hi%' then
return next xyz_row.city;
end if;
END LOOP;
close xyz;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
私が得るエラーは:
ERROR: relation "xyz" does not exist CONTEXT: compilation of PL/pgSQL function "avoidable_states" near line 4
RECORD
タイプを使用するだけです:
DECLARE
...
cur_row RECORD;
BEGIN
...
FETCH xyz INTO cur_row;
EXIT WHEN NOT FOUND;
IF cur_row.city LIKE 'CH%' THEN
...
FOR
loop の暗黙カーソルを使用する方が、やや遅い方法に頼るよりも、ほとんど常に優れています。扱いにくい明示カーソル。私は何千ものplpgsql関数を作成しましたが、明示カーソルが意味を成すのはほんの一握りの手だけでした。
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;
余談:関数には volatility VOLATILE
を必要とするものは何もありません。 STABLE
を使用します。
可能な場合は、セットベースのアプローチを使用することをお勧めします。使用する - RETURN 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;
単純な場合(おそらく単純化)には、単純な SQL関数 またはクエリだけを使用することもできます。
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;