• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:FETCH した行が取り出せない)

FETCHした行が取り出せない

このQ&Aのポイント
  • pgAdmin3を使用していて、条件に一致する行を複数取得し、アップデートを行いたいですが、カーソルを使用して一行ずつ処理をしようとしています。しかし、カーソル内のカラムの取得方法について詰まってしまっています。
  • postgresqlが不慣れで、カーソル内のカラムの取得方法について試行錯誤していますが、うまくいっていません。
  • pgAdmin3で条件に一致する複数の行を取得し、カーソルを使用して一行ずつ処理をしたいのですが、カーソル内のカラムの取得方法で困っています。誰か教えていただけると助かります。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.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();

motacilla
質問者

お礼

ありがとうございます。  plpgsqlを使えるように設定したりと時間がかかり、お礼が遅くなってしまいました。  今の所、まだ処理中で結果が返ってきておりませんが、エラーが出ておりませんので大丈夫のようです。  oracle→ポスグレの移行をしているのですが、勉強することが山ほどありそうです。    今回はありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

回答No.2

PostreSQLのカーソルについては詳しくないのですが。。。 「FROM句のサブクエリの書き方にミスがある」とエラーが出ているのだから、質問で省略されているSELECT文が分からなければ、回答のしようがありません。 「DECLARE car CURSOR IS ~」の最後のISはFORの転記誤り? カーソル宣言でエラーが出ているのだから、その後の処理は何もされないでしょうね。 #1さんの説明の「カーソルを使用した更新はできない」は、 「UPDATE 表名 SET 列名=値 WHERE CURRENT OF カーソル名」 という操作ができないという意味だと思うので、質問中の操作(検索条件指定のUPDATE)は該当しないと思われます。

motacilla
質問者

補足

有難うございます  ご指摘の通り、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)
回答No.1

「PostgreSQLはカーソルでの更新をサポートしていません」 ってことではないでしょうか? 以下公式マニュアルより 現時点では、PostgreSQLはカーソルでの更新をサポートしていません。したがって、FOR UPDATEを指定するとエラーメッセージが表示されます。

参考URL:
http://www.postgresql.jp/document/pg813doc/html/sql-declare.html
motacilla
質問者

お礼

 ご回答ありがとうございましたm(_”_)m

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ストアドプロシージャ_カーソルのヒット件数

    いつもお世話になっています。 SQLServer7.0です。 ストアドプロシージャでカーソルを使用し、オープンしたカーソルの件数を調べたいのですがうまくいきません。 Declare curs2 cursor for Select [項目名] From [テーブル名] Where [検索条件] Open curs2 Print @@CURSOR_ROWS この「@@CURSOR_ROWS」変数でヒット件数を取得できるように参考書では書いてあるのですが、実際Printしてみると、カーソルをオープンする前だと 0 で、オープンした後だと-1 です。 特にエラーだとか、対象データがないというわけではありません。実際その後ヒットした件数分行う処理は正常に出来ています。 ただ、どうしても処理を行う前に件数を知りたいのです。カーソルの変数だけでは取れないとなると セレクトしたカーソルと全く同じセレクトを実行して@@ROWCOUTで取るしかないかなって思ってるのですが・・・。どうも建設的ではないなって思ってます。 カーソルの件数を取得するにはどうしたらよいのでしょうか?

  • dbからデータをとりだす際、sqlのfetch結果をjavaでとりだす

    dbからデータをとりだす際、sqlのfetch結果をjavaでとりだすのは可能なのでしょうか? (チェックボックス 空欄) sql (チェックボックス 空欄) begin; declare cursor_name cursor for select * from user_ad; fetch forward 3 from cursor_name; //この結果をjavaでとりだしたい 注:この後、PostgreslqMyAdminで表そうとしたら、commitしたら表せない!! ふつうに、select文でとりだすなら分かるのですが。。。 con = Connectionのこと 処理ソースは、、、 必要最小限な部分だけ、記述しています。 PrepareStatement stmt = null; try { String sql = "select user_id from user_ad"; this.stmt = con.prepareStatement(sql); //ループでデータとりだし ResultSet rs = stmt.executeQuery(); while(rs.next()) { String userId = rs.getString("user_id"); } }catch(Exception e) { System.out.println(e.getMessage()); System.out.println(e.getStackTrace()); } fetchでとりだそうとすると、カーソルが関係していて、処理自体、変わってくるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • SQL xx件目からxx件目までを抽出したい

    SQLを習いはじめました。 ユーザーIDが100件あるテーブルの30件目~50件目の ユーザIDを抽出し、別テーブルに登録をしたいと思っています。 『このxx件目からxx件目まで』の抽出のしかたがわかりません。 どなたかわかる方がいましたら教えてください。 DECLARE CURSOR cursor_name IS SELECT USER_ID FROM TBL_USERID ; getid VARCHAR2(16); ryear NUMBER := '2008'; ryear2 NUMBER := '08'; rmonth NUMBER; rday NUMBER; usercnt NUMBER; rcnt NUMBER := '0'; --処理開始 BEGIN SELECT count(USER_ID) INTO usercnt FROM TBL_USERID ; OPEN cursor_name ; LOOP FETCH cursor_name INTO getid ; EXIT WHEN cursor_name%NOTFOUND; --月でループ(1~12月) For rmonth IN 1..12 LOOP --日でループ(1~22日) For rday IN 1..22 LOOP --スケジュール1件目 rcnt := (rcnt + 1); INSERT INTO TBL_SCH ( SCHEDULE_ID ,USER_ID ,UPDATE_DATETIME ) VALUES ( ryear || Trim(TO_CHAR(rmonth,'00')) || Trim(TO_CHAR(rday,'00')) || Trim(TO_CHAR(rcnt,'00000000')) ,'getid' ,SYSTIMESTAMP ); END LOOP; END LOOP; END LOOP ; CLOSE cursor_name ; END ;

  • カーソルについて

    カーソルってオープン時に該当データの全レコードセットを取得するんでしょうか?。 PL/SQLでVIEWのカーソルをオープンし、ループ処理を行っているんですが、処理速度からして1フェッチごとに毎回SELECT文を発行しているように見受けられます・・・。 ソースはこんな感じです↓。 declare cursor cur_tb_1 is select * from ビュー; begin for rec_tb_1 in cur_tb_1 loop ...処理いろいろ end loop; end; また、このようなケースの場合、VIEWのSELECT結果を一時テーブルにINSERTし、そのテーブルをSELECTするカーソルを使用するほうが 作法的によいのでしょうか?

  • 動的なSQLからカーソルを返す。

    下記のようなカーソルを返すパッケージがあったとします。 CREATE OR REPLACE PACKAGE TEST AS CURSOR C1 IS SELECT * FROM テーブル; TYPE TC1 IS REF CURSOR RETURN C1%ROWTYPE; PROCEDURE P_TEST(in条件 IN CHAR, CU OUT TC1); END; CREATE OR REPLACE PACKAGE BODY TEST IS PROCEDURE P_TEST(in条件 IN CHAR, CU OUT TC1) AS sqlStr VARCHAR2(1000); cur NUMBER; r NUMBER; BEGIN cur := DBMS_SQL.OPEN_CURSOR; sqlStr := 'OPEN CU FOR SELECT * FROM テーブル WHERE 条件 = ' || in条件; DBMS_SQL.PARSE(cur, sqlStr, DBMS_SQL.NATIVE); DBMS_SQL.DEFINE_COLUMN(cur, 1, CU); r := DBMS_SQL.EXECUTE(cur); DBMS_SQL.CLOSE_CURSOR(cur); END; SELECTした結果のカーソル(CU)をクライアントで取得したいのですけど 技術的に可能でしょうか? ストアドのコンパイル時に→DBMS_SQL.DEFINE_COLUMN(cur, 1, CU);が エラーとなります。 DBMS_SQL.DEFINE_COLUMNではカーソルタイプは取得できないとわっかたの ですがカーソルを取得する為のDBMS_SQL.DEFINE_COLUMNにかわる DBMS_SQL.?????はないでしょうか? いろいろ調べたのですが手に負えず。 どなたか教えてください。

  • ストアド内でカラム名一覧を取得

    =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ストアド内でカラム名一覧を取得、カンマで繋げてひとつの変数にまとめたい。 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 現在開発でストアドを使用する機会があり、そこで不明点が発生し悩んでおります。 以下、現状と質問です。 ■SQL SERVER 2000 ■テーブル(※)のカラム名一覧を取得し、  カラム名をカンマで繋げてひとつの変数に格納したいと思っています。  ※先の処理でカラムを取得したいテーブルをSELECTしており、  対象のテーブル名を変数に代入しています。  カラム一覧を取得するにあたり、以下のようにカーソルで習得し、  FETCHでカラム名を変数に格納しようと考えていましたが、  「'対象テーブル名'」には変数がいれられないので、どうしようかと悩んでいます。  DECLARE CURS_test CURSOR FOR   SELECT name FROM dbo.syscolumns   WHERE id IN   (SELECT id FROM dbo.sysobjects WHERE name = '対象テーブル名')   ORDER BY id, colid;  「sp_executesql」を使用してselect文を流そうとしたのですが、  複数ある列名を取得して、上記で記載しましたように  カラム名をカンマで繋げてひとつの変数に格納する方法がわかりませんでした。  こういった場合、どのように考えて、どのように書けばよいのでしょうか。  まだ触り始めたばかりで、わからないことがわかっていない部分もあり、  質問内容でわかりにくい部分がありましたらご指摘いただければと思います。  どうぞよろしくお願いいたします。

  • csvデータの開始行と最終行を全体の4分の1で区切り処理をしたい

    csvデータの開始行と最終行を全体の4分の1で区切り処理をしたい csvデータの開始行と最終行を全体の4分の1で区切り処理をしたいと思ってます。 csvファイルは20万件あります。4分の1なので1~50000件となります。 今回は50001~100000件までを行いたいのですが、先日教えていただいたwhile($lines = <IN>) ですと、最初から1件ずつ最終行まで処理をしてしまいます。 (ここから) open(OUT,">$csv"); open(IN,"$data") || &error(" $data を読み込みopen出来ません"); while($lines = <IN>) { ($seq1,$categ,$password,$imail,$cont) = split("\,", $lines); $cont .= " "; $data = "$seq1,$cont,1\n"; print OUT "$data"; $data = ""; } close IN; close OUT; (ここまで) 今回は20万件ですが、毎回このデータ量は月次ごとに変わります。 while周辺をいじるような気がしていますがどのようになるのかがわからなかったので質問いたしました。 お手数かけます。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • ストアドプロシージャにてフェッチから出ない

    Aというテーブルの情報をカーソルにて取得し、 同じくAというテーブルに項目を変えてInsertするという プロシージャを作成しています。 しかし、フェッチしたあとその処理から出ません。 (ちなみにフェッチ後のBEGIN~END内のInsert文を違うテーブルにして実行してみると処理から抜けました) 下記が該当プロシージャです。 CREATE PROCEDURE 販売プロシージャ AS BEGIN --変数宣言 DECLARE @販売NO INT DECLARE @顧客NO INT DECLARE @明細 NVARCHAR(25) DECLARE @受注日 SMALLDATETIME DECLARE @金額 INT DECLARE @ステータス BIT DECLARE @有効フラグ BIT --カーソル宣言 DECLARE 販売カーソル CURSOR FOR SELECT 販売NO, 顧客NO, 明細, 受注日, 金額, ステータス, 有効フラグ FROM 販売 WHERE YEAR(受注日) = YEAR(GETDATE()) AND MONTH(受注日) < MONTH(GETDATE()) --初期化処理 SET NOCOUNT OFF --カーソルOPEN OPEN 販売カーソル FETCH NEXT FROM 販売カーソル INTO @販売NO, @顧客NO, @明細, @受注日, @金額, @ステータス, @有効フラグ WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO 販売 ( 販売NO, 顧客NO, 明細, 受注日, 金額, ステータス, 有効フラグ, 登録日, 更新日, )VALUES( @販売NO, @顧客NO, @明細, @受注日, @金額, @ステータス, @有効フラグ, GETDATE(), GETDATE(), ) FETCH NEXT FROM 販売カーソル INTO @販売NO, @顧客NO, @明細, @受注日, @金額, @ステータス, @有効フラグ END CLOSE 販売カーソル DEALLOCATE 販売カーソル END 同じテーブルを使用する場合は、このような記述ではできないのでしょうか?

  • PL/SQLの動的SQLで複数の項目を取得する方法教えて下さい。

    動的SQLで複数の項目を取得する方法で 悩んでいます。 下記の例だと、1項目しか取れません。 何か他のやり方でもいいので、複数の項目を 取得する方法を教えていただきたいです。 ********************************************* declare sql_stmt varchar2(200); wk_grp varchar2(5); wk_name varchar2(30); type cursor_type is ref cursor; cur_name cursor_type; begin wk_grp := '1u'; open cur_name for 'select 名前 from 社員表 where 所属グループ = :v1' using wk_grp; loop fetch cur_name into wk_name; exit when cur_name%notfound; dbms_output.put_line(wk_name); end loop; close cur_name; end; ********************************************* 下記のようなDBMS_SQLパッケージ?? を利用した方法がいいんでしょうかね。。。。 DBMS_SQL.COLUMN_VALUE(SQL,1,WK_NAME) DBMS_SQL.COLUMN_VALUE(SQL,2,WK_NO) よくわかってないので、宜しくお願いします。

  • Perlで行頭にある文字が含まれている行を全部削除して詰めたい

    perl初心者です。以下のようにデータがならんでいる時、 test111 aaaaaaaaabbbbbbbbcccccc test112 aaaaccccabbbbbbbbcccccc test113 aaaaccaaabbbbbbbbcccccc test114 acccaaaaabbbbbbbbcccccc test111 aacaaaaaabbbbbbbbcccccc test112 accaaaaaabbbbbbbbcccccc test113 aaacccaaabbbbbbbbcccccc test114 aaaaaccaabbbbbbbbcccccc test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。 途中からわかりません。 行を削除する関数が調べても見つからないのです。 #!/usr/bin/perl ; open(IN, "test.doc") or die ; open(OUT, ">testout.doc"); while(<IN>) { chomp ; if (/(\S+)/) { $name = $1 ; if ($name =~ /^test112(\S+)/) { #ここでマッチさせて、一気に行を削除して、しかも行を詰めたいのですが ; } print OUT " \n" ; } } close (IN) ; close (OUT) ; 大変困っております。宜しくお願いします。

    • ベストアンサー
    • Perl