iakioの日記 RSSフィード

2008-05-20

PREPARED STATEMENTにカーソルを渡す

| 11:52 | PREPARED STATEMENTにカーソルを渡す - iakioの日記 を含むブックマーク はてなブックマーク - PREPARED STATEMENTにカーソルを渡す - iakioの日記

ところで、更新可能カーソルについて調べてみたらgram.yは

where_or_current_clause:
            WHERE a_expr                            { $$ = $2; }
            | WHERE CURRENT_P OF name
                {
                    CurrentOfExpr *n = makeNode(CurrentOfExpr);
                    /* cvarno is filled in by parse analysis */
                    n->cursor_name = $4;
                    n->cursor_param = 0;
                    $$ = (Node *) n;
                }
            | WHERE CURRENT_P OF PARAM
                {
                    CurrentOfExpr *n = makeNode(CurrentOfExpr);
                    /* cvarno is filled in by parse analysis */
                    n->cursor_name = NULL;
                    n->cursor_param = $4;
                    $$ = (Node *) n;
                }
            | /*EMPTY*/                             { $$ = NULL; }

となっていました。2つ目のWHERE CURRENT_P OF PARAMって何だろうと思ったら、どうやら$1とか$2のことのようです。もしかしてPREPARED STATEMENTにパラメータとしてカーソルを渡せるのかな。

db1=> prepare p1(refcursor) as delete from t1 where current of $1;
PREPARE
db1=> begin;
BEGIN
db1=> declare cur1 cursor for select * from t1;
DECLARE CURSOR
db1=> fetch cur1;
 i
---
 1
(1 row)

db1=> execute p1('cur1');
DELETE 1

ほほお。executeの時はカーソル名を文字列として渡すのがポイントのようです。

更新可能カーソル

| 11:11 | 更新可能カーソル - iakioの日記 を含むブックマーク はてなブックマーク - 更新可能カーソル - iakioの日記

まだ使ったことがない8.3の新機能をちょろちょろ調べます。

更新可能カーソルの使い方は、(DELETE又はUPDATE) ... WHERE CURRENT OF [カーソル名];だそうです。これでユニークなキーを持たないテーブルから1行だけ削除なんていうのも簡単にできるようになりますね。

db1=> SELECT * from t1;
 i
---
 1
 1
 1
(3 rows)

db1=> begin;
BEGIN
db1=> declare cur1 cursor for select * from t1;
DECLARE CURSOR
db1=> fetch cur1;
 i
---
 1
(1 row)

db1=> delete from t1 where current of cur1;
DELETE 1
db1=> select * from t1;
 i
---
 1
 1
(2 rows)

db1=> commit;
COMMIT

WHERE CURRENT OFは最後にfetchした行を表すので、まだ一度もfetchしていなければエラーとなります。

db1=> delete from t1 where current of cur1;
ERROR:  cursor "cur1" is not positioned on a row
トラックバック - http://postgresql.g.hatena.ne.jp/iakio/20080520