8.3では更新可能カーソルが使えるようになった。従来、PostgreSQLのカーソルは「更新不可能」だったのである。

次の例を見ていただきたい。

BEGIN;
DECLARE c CURSOR FOR SELECT * FROM T1;
FETCH 2 FROM c;
 i |  j
---+-----
 1 | foo
 2 | bar
(2 rows)

この状態で1行削除する。

DELETE FROM t1 WHERE i = 1;

しかし、カーソルを使って確認すると、削除されていないように見える。これがPostgreSQLのカーソルが「更新不可能」と言われる理由である。

MOVE BACKWARD ALL IN c;
FETCH ALL FROM c;
 i |  j
---+-----
 1 | foo
 2 | bar
(2 rows)

もちろん、実際には削除されており、SELECT文で確認できる。

SELECT * FROM t1;
 i |  j
---+-----
 1 | foo
(1 row)

これに対して8.3では、FOR UPDATEをカーソル宣言に付与することにより、カーソルを更新可能にできる。

BEGIN;
DECLARE c CURSOR FOR SELECT * FROM T1 FOR UPDATE;
FETCH 2 FROM c;
 i |  j
---+-----
 1 | foo
 2 | bar
(2 rows)

ここで1行削除してみる。ちなみに、「WHERE CURRENT OF」は8.3で導入された構文で、カーソルが指す現在行を指定する。

DELETE FROM t1 WHERE CURRENT OF c;

カーソルからも削除されていることが確認できる。

MOVE BACKWARD ALL IN c;
FETCH ALL FROM c;
 i |  j
---+-----
 1 | foo
(1 rows)

更新可能カーソルが使えるようになったことにより、カーソルの扱いに関しては商用DBからの移行が格段に楽になったと言える。