- ベストアンサー
FETCHした行が取り出せない
- pgAdmin3を使用していて、条件に一致する行を複数取得し、アップデートを行いたいですが、カーソルを使用して一行ずつ処理をしようとしています。しかし、カーソル内のカラムの取得方法について詰まってしまっています。
- postgresqlが不慣れで、カーソル内のカラムの取得方法について試行錯誤していますが、うまくいっていません。
- pgAdmin3で条件に一致する複数の行を取得し、カーソルを使用して一行ずつ処理をしたいのですが、カーソル内のカラムの取得方法で困っています。誰か教えていただけると助かります。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#2回答者です。 「FETCH ALL IN カーソル名」の使い方がよく分からなかったので、代替案としてPL/pgSQLを使用する方法を考えてみました。 (1)関数の定義 recという行データ受け取り変数を使い、受け取った特定列の参照は、「変数名.列名」で行えます。 create function functest1() returns int as ' declare car cursor for select * from t1; rec record; begin open car; loop fetch car into rec; if not found then exit; end if; update t2 set c2=0 where c3=(select c3 from t3 where c1=rec.c1); end loop; close car; return 0; end; ' language 'plpgsql' ; (2)関数の実行 select functest1(); (3)関数を削除する場合 drop function functest1();
その他の回答 (2)
- chukenkenkou
- ベストアンサー率43% (833/1926)
PostreSQLのカーソルについては詳しくないのですが。。。 「FROM句のサブクエリの書き方にミスがある」とエラーが出ているのだから、質問で省略されているSELECT文が分からなければ、回答のしようがありません。 「DECLARE car CURSOR IS ~」の最後のISはFORの転記誤り? カーソル宣言でエラーが出ているのだから、その後の処理は何もされないでしょうね。 #1さんの説明の「カーソルを使用した更新はできない」は、 「UPDATE 表名 SET 列名=値 WHERE CURRENT OF カーソル名」 という操作ができないという意味だと思うので、質問中の操作(検索条件指定のUPDATE)は該当しないと思われます。
補足
有難うございます ご指摘の通り、IS は、FORの転記間違いでした。 サブクエリの中を含めて書くと BEGIN; DECLARE car CURSOR FOR SELECT 列名1 AS 列仮名1 from 表1; FETCH ALL IN car; UPDATE 表2 SET 列名2 = 値 WHERE 列名3 = ( SELECT 列名3 FROM 表3 WHERE 列名1 = car.列仮名1 ); CLOSE car; END; のような感じになります。(省略してございますが) missing FROM-clause entry in subquery for table "car" のエラーが「car.列名 で、カーソルの特定列名の値を取得」 という文章の指定が違うという意味かなと思い(carをテーブル別名とみなされているような気がして)、 カーソル内の列を取り出してSQLに使用するには、どんな記述になるのかなとご質問させていただいた次第でございます。
- nino2
- ベストアンサー率88% (8/9)
「PostgreSQLはカーソルでの更新をサポートしていません」 ってことではないでしょうか? 以下公式マニュアルより 現時点では、PostgreSQLはカーソルでの更新をサポートしていません。したがって、FOR UPDATEを指定するとエラーメッセージが表示されます。
お礼
ご回答ありがとうございましたm(_”_)m
お礼
ありがとうございます。 plpgsqlを使えるように設定したりと時間がかかり、お礼が遅くなってしまいました。 今の所、まだ処理中で結果が返ってきておりませんが、エラーが出ておりませんので大丈夫のようです。 oracle→ポスグレの移行をしているのですが、勉強することが山ほどありそうです。 今回はありがとうございました。