PL/pgSQLは、PostgreSQLデータベースシステム用の読み込み可能な手続き言語なのですが、テーブル走査をする方法としてカーソルが提供されています。今回は、このカーソルを扱うときの処理についてみてみましょう。
サンプルとかでよく見かける例
適当なテーブル(ここでは、user_id, nameを持つ、usersとしました。)を走査する場合、下記のような例をよく見かけます。
CREATE OR REPLACE FUNCTION
funcXXX()
RETURNS VOID AS $$
DECLARE
var_rec RECORD;
var_cursor CURSOR FOR SELECT user_id, name FROM users;
BEGIN
OPEN var_cursor;
LOOP
FETCH var_cursor INTO var_rec;
IF NOT FOUND THEN
EXIT;
END IF;
RAISE NOTICE 'row1=%, row2=%', var_rec.user_id, var_rec.name;
END LOOP;
CLOSE var_cursor;
END;
$$ LANGUAGE plpgsql;
正直、OPEN, CLOSEは良いのですが、FOUNDという変数の結果がFalseの場合、処理をやめる(EXIT)するというこのロジック、正直わかりづらいと感じますね。
FOR LOOPを使って同じことを書く
下記のようになります。
CREATE OR REPLACE FUNCTION
funcXXX()
RETURNS VOID AS $$
DECLARE
var_cursor CURSOR FOR SELECT user_id, name FROM users;
BEGIN
FOR var_rec IN var_cursor LOOP
RAISE NOTICE 'row1=%, row2=%', var_rec.user_id, var_rec.name;
END LOOP;
END;
$$ LANGUAGE plpgsql;
Open, Close, FOUND、Fetch自体もなくなり非常にすっきりしています。おまけにvar_recというレコードを保存するための変数の宣言もなくなります。
カーソル走査をイディオム的に覚えるのなら、For Loopを使う形式
FOR var_rec IN cursor LOOP
-- レコードに対して必要な処理を行う
END LOOP;
で覚えることをおすすめします。