• 締切済み

JDBCでテーブルUPDATE後の再検索でエラー

お世話になります。 ORACLEでUPDATEに失敗(抽出条件に一致するレコード無し)した後、同一テーブルのレコードを再検索するとSQLExceptionが発生してしまいます。原因、対策をご存知の方がおられましたら、ご教授ください。よろしくお願い致します。 (1)table_1からFieldAの値を取得する。(ここでは"001"だったとする) select FieldA from table_1 where FieldB='XXX'; (2)FieldAから取得した値を変更する("001"から"002"に変更) その他諸々の業務処理を行う (3)update table_1 set FieldA='002' where FieldB='XXX' and FieldA='001'; (4)更新がOKだったら処理終了。 (5)同一レコードのFieldAの値を他のプロセスが既に更新済みだった場合、update件数が0となるので、 (1)からリトライを行う。 ⇒この時、(1)の再検索でResultsetのexecuteQueryの後、next()メソッドで「ORA-01002: フェッチ順序が無効です。」となってしまいます。

  • Java
  • 回答数1
  • ありがとう数1

みんなの回答

  • PCFREAK
  • ベストアンサー率51% (417/805)
回答No.1

(1)と(3)のStatement、Resultsetオブジェクトを使い回しているのではないですか? 参照用と更新用で分けて下さい。 また、(1)からリトライする直前(ループの終端)に必ずStatement、Resultsetをclose()する様にして下さい。

関連するQ&A

  • 複数テーブルからデータを取り、updateする

    http://oshiete1.goo.ne.jp/kotaeru.php3?q=1211685 にも同じような質問があったのですが、同様の処理でうまくupdateされません。分かる方がいらっしゃいましたら教えてください。 今、テーブルが2つ(table1、table2)があり、それぞれ2つのカラム(column1、column2)を持っています。ここで、それぞれのカラム2が等しく、カラム1が指定した値のレコードのみ値をupdateしたいです。 update table1 set column1 = 'AAA' from table1,table2 where table1.column2 = table2.column2 and table1.column1 = 'BBB' and table2.column1 = 'CCC' としたところ、「from table1,table2 where 」の辺りに間違いがあると表示されます。 上の例とどう違うのか分かりません。 よろしくお願いします。m(__)m

  • 1テーブル&複数レコードの更新に対して1度のupdate文での処理方法

    1テーブル&複数レコードの更新に対して1度のupdate文での処理方法 Delphi2010+SQL SERVER 2005で開発しています。 update文で、 現在下のようにwhileで複数レコードに対して、 1回、1回、sqlを発行して、更新しています。 これを、一度のSQLの発行で処理できないものでしょうか? 更新テーブルは1つで、更新する項目も同じです。 更新するデータと、where句の条件が異なります。 もし可能なようでしたら、どうかご教授お願いします。 update table set A=1,B=2 where id=1 update table set A=2,B=3 where id=5 update table set A=9,B=99 where id=7 update table set A=5,B=10 where id=15 update table set A=1,B=10 where id=75

  • PostgreSqlのテーブルをVBから更新

    PostgreSqlのテーブルをVBから更新 【テーブル】 tbl1 ( item1 integer not null, -- 数値:ユニークキー , item2 character varying, -- 文字 , item3 timestamp without time zone -- タイムスタンプ , CONSTRAINT tbl1pk PRIMARY KEY (item1) ) 【仕様】 1.テーブル内の特定の1レコードを取得 2.取得したレコードをVBの画面に表示 3.入力:VBの画面で item2 の表示内容を変更 4.ボタン入力 4-1.レコードが存在しない場合  メセージボックスに「誰かが消した」と表示 4-2.タイムスタンプに変化がある場合  メセージボックスに「誰かが変更した」と表示 4-3.タイムスタンプに変化がない場合  Updateする。 【前提】 普通にアップデートするだけなら、下記でできました。 Private DateTime1 As DateTime ' 画面表示の時に取得したitem3の値が入っているとする  :  : Dim NpgsqlConnection1 As NpgsqlConnection = New NpgsqlConnection Dim NpgsqlCommand1 As NpgsqlCommand = New NpgsqlCommand NpgsqlCommand1 = NpgsqlConnection1.CreateCommand NpgsqlCommand1.CommandText = "update tbl1 " _ & "set item2 = '" & Me.TextBox1.Text & "'" _ & ", item3 = current_timestamp " _ & "where item1 =" & キー値 NpgsqlConnection1.ConnectionString = 接続情報 NpgsqlConnection1.Open() NpgsqlCommand1.ExecuteNonQuery() NpgsqlConnection1.Close() 【考察】 変更された場合は、更新対象外にするのは、条件に入れればなんとかなります。 NpgsqlCommand1.CommandText = "update tbl1 " _ & "set item2 = '" & Me.TextBox1.Text & "'" _ & ", item3 = current_timestamp " _ & "where item1 =" & キー値 _ & "and date_trunc('second', item3) =" & "to_timestamp('" & Format(DateTime1, "yyyy-MM-dd HH:mm:ss") & "', 'YYYY-MM-DD HH24:MI:SS')" しかし、これではこのSQLで更新されたのか、他で更新があったためにスキップしたのかが分かりません。 直前のSQLで更新があったかどうか、もしくは何件更新対象になったかを得る事はできませんか? もしくは、 一旦呼び出してロックし、その間にタイムスタンプを取り出し、 Vb内に持っていた前回のタイムスタンプと比較し、同じであれば更新する。 同じでなければステータスを返す。 というふうにしたいです。 【質問】 アップデート文で更新対象になった件数を取得する事はできませんか? もしくは、フェッチの方法を教えて下さい。 上記の仕様のようにタイムスタンプを判断し、そのレコードを掴んだままアップデートしたいなら、フェッチするしかないのかと思っています。 でも、そのやり方が分かりません。 ・コネクト ・カーソル定義 ・カーソルオープン ・ネクストレコード ・レコードを取得し、VB側のタイムスタンプと比較←どうやって? ・カーソル行に対しアップデート ・レコードの終わり ・0件なら「誰かが消した」と表示 ・カーソルクローズ ・コネクト解除 やりたい事は上記でSqlもVbも分かるのですが、インターフェイス込みでコマンドレベルの方法が分かりません。 フェッチでの方法が分からないので教えて下さい。 フェッチで以外の方法で同等の事が出来るもっと良いやり方があれば教えて下さい。 以上、よろしくお願いします。

  • JDBCのDB検索

    import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.mysql.jdbc.PreparedStatement; import com.mysql.jdbc.Statement; public class AddressDB { private static enum Procnumlist { NAME("名前"), FNAME("フルネーム"), END("終了"); private String name; private Procnumlist(String name) { } } //上の列挙型を基にした処理判定用マップを作成 private static final Map<Integer, Procnumlist> procmap; static { procmap = new HashMap<Integer, Procnumlist>(); procmap.put(1,Procnumlist.NAME); procmap.put(2,Procnumlist.FNAME); procmap.put(6,Procnumlist.END); } //結果 //ResultSetは受け取らない private static void ans(List<Addr> ans) { try { System.out.println("検索結果"); for (int i = 0; i < ans.size(); i++) { Addr addr = ans.get(i); System.out.println(addr.getName() + ":" ); } } catch (SQLException e) { e.printStackTrace(); } finally { //閉じる。 close(); } } //名前検索(フルネーム) private static List<Addr> srchFName(String keyword,Connection con) throws IOException { String sql = "SELECT * FROM data2 where name=?"; PreparedStatement ps = null; try{ ps = (PreparedStatement) con.prepareStatement(sql); ps.setString(1,keyword); ResultSet rs = ps.executeQuery(); //List<Addr> result = new ArrayList(Addr); while(rs.next()){ rs.getString("name"); } }catch (SQLException ex) { } return null; } //名前検索 private static List<Addr> srchName(String keyword,Connection con) throws IOException { String sql = "SELECT * FROM data2 where name like ?"; PreparedStatement ps = null; try{ ps = (PreparedStatement) con.prepareStatement(sql); ps.setString(1,"%"+keyword+"%"); ResultSet rs = ps.executeQuery(); while(rs.next()){ Addr addr = rs.getString("name"); } }catch (SQLException ex) { } return result; } private static boolean checkProcNum(int value) { return procmap.get(value) != null; } public static void main(String[] args)throws IOException{ while(true) { createConeection(); //処理条件入力 System.out.println("検索\n1.名前(ファーストネーム)で検索\n2.フルネームで検索\n6.終了"); //検索値入力 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int procnum = Integer.valueOf(br.readLine()); //入力チェック if (!checkProcNum(procnum)) { System.out.println("正しい値を入れてください。"); continue; } Procnumlist proc = procmap.get(procnum); if (proc == Procnumlist.END) { break; } if(proc == Procnumlist.NAME){ System.out.println("名前を入力してください。"); BufferedReader name = new BufferedReader(new InputStreamReader(System.in)); String keyword = name.readLine(); List<Addr> result = srchName(keyword,null); ans(result); } if(proc == Procnumlist.FNAME){ System.out.println("フルネームを入力してください。"); BufferedReader name = new BufferedReader(new InputStreamReader(System.in)); String keyword = name.readLine(); List<Addr> result = srchFName(keyword,null); ans(result); } } } //コネクション private static Connection createConeection() { String url = "jdbc:mysql://localhost/address"; String user = "test"; String password = "pass"; try { return DriverManager.getConnection(url, user, password); } catch (SQLException e) { e.printStackTrace(); return null; } } } 現在JDBCでDB接続し入力された値をDBから検索し出力するものを作成しておりますが詰んでしまいました。 入力した値をsrchで検索し結果をansで出力しようとしています。どのようにしたらよいのでしょうか

  • update文に条件をつける場合

    update文に条件をつける場合 初心者です。よろしくお願いします。 update TABLE set HOGE = replace(HOGE,'文章','ブンショウ') こちらのupdate文にもう一つ条件をつけたいのですが、WHERE句をいれるとエラーがでてしまいます。 update TABLE set HOGE WHERE XXX = "YYY" = replace(HOGE,'文章','ブンショウ') update TABLE set HOGE WHERE XXX = "YYY" AND replace(HOGE,'文章','ブンショウ') エラーがでてしまいます、、、、WHERE XXX = "YYY"のような条件をだしたい場合はどのようにしたら良いでしょうか。 よろしくお願いします。m(_ _)m

    • ベストアンサー
    • MySQL
  • ACCESS2002のupdateの副問合せについて教えてください

    ひとつのテーブルの情報を、もうひとつのテーブルに反映させられなくて困っています。 おそらくupdateの副問合せの書き方が悪いと思うのですが、どこが悪いのか分かりません。 access2002 VBAで、同じフィールド構成を持つ2つのテーブルがあります。 TABLE_A -------------------------- |P_Key | Field1 | Fieled2| +------+--------+--------+ |111111|AAAA|BBBB| |222222|CCCC|DDDD| |333333|EEEE|FFFF| |444444|GGGG|HHHH| -------------------------- TABLE_B -------------------------- |P_Key | Field1 | Fieled2| +------+--------+--------+ |222222|ZZZZ|YYYY| |333333|XXXX|WWWW| -------------------------- このうち、ひとつのテーブル(TABLE_A)のField1 と Field2 の値を もうひとつのテーブル(TABLE_B)のField1 と Field2 の値に変更したいのです。 条件は、P_Keyが同一のレコード同士です。 実行結果は以下のようにしたいのです。 TABLE_A (TABLE_Bは更新しないため変更無し) -------------------------- |P_Key | Field1 | Fieled2| +------+--------+--------+ |111111|AAAA|BBBB| |222222|ZZZZ|YYYY| |333333|XXXX|WWWW| |444444|GGGG|HHHH| -------------------------- VBAでupdateのSQLを書いているのですが、うまくいきません。 以下のSQLではDMLが正しくないのエラーになってしまいます。 (すみません。正式なエラーメッセージは失念しました) update TABLE_A set( TABLE_A.Field1,TABLE_A.Field2 ) = ( select TABLE_B.Field1,TABLE_B.Field2 from TABLE_B where TABLE_A.P_Key = TABLE_B.P_Key ); テーブル名に別名をつけたりしても同様にDMLが正しくないと怒られます。 質問は、以下の2つです。 1.上記更新は、ひとつのupdateのSQLで可能でしょうか?   それともTABLE_B を Selectでまわして、TABLE_Aのレコードを一行ずつ   更新していく必要があるのでしょうか? 2.1.が可能の場合、私の書いたSQLについてご助言をいただけませんでしょうか? もしご存知の方おられましたら、ご教示をお願いできませんでしょうか? 以上です

  • まとめてUPDATEしたいのですが。

    まとめてUPDATEしたいのですが。 下記のようなUPDATE文を実行したいのですが、思ったとおりの動作をしません。 UPDATE table1 AS TB1 INNER JOIN table2 AS TB2 ON TB1.table2_id=TB2.id SET TB2.point = TB2.point - TB1.remainder_point, TB1.remainder_point = 0 WHERE TB1.remainder_point > 0 最初の1レコード目だけ「TB2.point = TB2.point - TB1.remainder_point」が実行されますが、 その後のレコードが「TB1.remainder_point = 0」で値が全て0になるらしく、減算処理が行われません。 上手くまとめて実行できる良い書き方は無いでしょうか。

  • mysqlのupdateはどこでやるのですか?

    ものすごい愚問だったらすみません。 mysqlのデータをupdateするのはどこでするのですか? 今はhp上に xxx.phpをつくり、phpで今日の日付を取得し、複数のmysqlテーブルから条件抽出selectし、、、と値を出し、xxx.phpで $sql_l = "UPDATE table名 SET tyo{$month} = '{$ticket_city_month[price]}' WHERE cityname = '{$cityname}'"; $result = mysql_query($sql_l); とし、ブラウザ上から更新して、updateしています。 一応UPDATEはできているのですが、数が多く一気にできません。 (select時にデータ量を少なくするため、あえてwhereで一部ずづやってます。) phpMyAdmin 2.6.0 MySQL 4.1.20 で、 phpMyAdminとNavicat MySQLも利用しています。

  • UPDATEの更新前の値を取得したい

    SQLServer2008を使用して、 UPDATEの更新前と更新後の差分を出そうとしているのですが、 更新前の値が取れません。 更新後の値はOUTPUT句を使用してINSERTED.XXXでとっています。 更新前の値もOUTPUT句を使用してDELETED.XXXでとれるのかと思い試したら INSERTED.XXXと同じ値(更新後の値)が取れてしまいました。 selectをしずに、更新前の値を取得する方法はありますでしょうか? ご存知の方ご教授お願いいたします。

  • Javaのエラーについて

    JavaでMySQLを使ったプログラムを作成中です。 もちろんJDBCを使ってます。 SQLを実行すると java.sql.SQLException:Can not issue data manipulation statements with executeQuery() というエラーになります。 SQLは update logt set naiyou='musi' where name='fukuoka'; です。 どうもSELECT文のSQLは動くみたいですが、UPDATEやINSERTはエラーになるみたいです。 原因がわかりません。 教えてください。

    • ベストアンサー
    • Java