オラクルのDBでカーソルがコミットするとクローズされてしまう問題について

このQ&Aのポイント
  • オラクルのDBで環境はUNIX(IBMのマシン)です。特定のキーの昇順に全レコードを読み込み、他のDBを更新する処理を行いたい。しかし、コミット(又はロールバック)を行うことにより、カーソルがクローズされ、最初の位置に戻ってしまう問題が発生している。
  • 問題の解決策について、具体的なアドバイスを求めています。カーソルが戻らずに全レコードを処理する方法についてご存知の方がいらっしゃいましたら、教えていただきたいです。
  • また、オラクルのDBについて詳しくないため、この問題を解決するために必要な知識や手順についても教えていただけると助かります。
回答を見る
  • ベストアンサー

カーソルがコミットするとクローズされてしまう。

オラクルのDBで環境はUNIX(IBMのマシン)です。 DBについて詳しくありませんが、以下のようなことを行いたいと考えています。 1.あるDB(DB-A)のレコードを特定のキーの昇順に全レコード読み込む。(特定のキーは、例えば商品コードなど) 2.1レコードを読み込む毎に、他のDB(DB-B)を読み込んだレコードを元に、更新したい。 その際、1レコードを読み込む都度、 2-1.トランザクションの開始 2-2.DB-Bの更新 2-3.コミット又はロールバック のようにしたい。 上記のことを考えて以下のような作りにしました。 1.カーソルのオープン 2.以下のループを作成  2-1.DB-Aから1レコードのフェッチ  2-2.トランザクションの開始  2-3.DB-Bの更新  2-4.コミット(ロールバック) しかしながら、コミット(又はロールバック)を行うことにより、カーソルがクローズされてしまい、最初の位置にカーソルが戻ってしまいます。(私がコーディングして試験したわけではありません。このような報告をうけました) それで、カーソルが戻らずに、全レコードを処理するようにしたいのですが、どのようにしたら良いのでしょうか。ご存じの方おりましたらアドバイスをお願いします。

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

  • ベストアンサー
  • paz777
  • ベストアンサー率47% (77/163)
回答No.1

こんにちは。 私が経験した中ではフェッチをするテーブルに対して[for update]している場合に途中でコミット処理を行うとカーソルが破壊される現象がありました。 ご質問の現象はDB-Aに対してupdateはしていないようなので原因は違うところにあるかも知れませんので、取り敢えず以下のチェックを行ってみて下さい。 1.コミット処理を全てのレコードが処理された後に行ってみる。 2.ループの中にカーソルのオープン処理が入っていないか確認。 3.SQLエラー時(Null Getも含み)にカーソルのオープンまで処理が戻らないか確認。 考えれるのはこれくらいですかね。 上記[1.]の処理で正常に動作するようであればそれで良いと思います。 但し、この場合にはロールバックセグメントにかなり余裕が必要(大きく定義する)になりますのでご注意ください。 余談ですが、1件毎にコミット処理を行うのは非常に効率がよくないと思います。 ではでは・・・

tatsu99
質問者

お礼

返事が送れて申し訳ありませんでした。結局本件は、「オラクルの仕様としてそのようなことはやってはいけないことになっている」という結論に至り、質問に書いたようなやり方を採用しないことで、決着がつきました。しかしながら、回答を拝見すると、「仕様としてできないことはなく、出来るはず」のように思われますので、自分で機会があれば、確認してみます。ありがとうございました。

関連するQ&A

  • トランザクション中に別のトランザクションは開始できますか?

    DBはサイベースを使っています。初心者です。 以下のような動作をしているシステムの一部を改造することになりました。 1)カーソルAオープン 2)トランザクション開始 3)フェッチ 4)1トランザクションでの処理数分終了済みでなければ、3)から繰り返し 5)commit/rollback 6)終了済みでなければ 2)から繰り返し 7)カーソルAクローズ 今回、3)でフェッチしたレコードのある項目をキーとして 別のテーブルを検索しなければならないのですが、 3)の後に、カーソルBオープンとフェッチのみを追加しただけでは問題があると思うのですが、同一プロセスから、トランザクション中に別のトランザクションを開始することは可能なのでしょうか? なお、このトランザクションでは、レコードの追加や削除は行いません。 どうぞよろしくお願いいたします。

  • トランザクションを張って対話型でのコミット・ロール

    トランザクションを張って更新処理を行った後に、 ユーザの「はい」「いいえ」ボタンによって、 トランザクションのコミットとロールバックを切り替えることは可能でしょうか。 処理の流れは以下の様になります。 1.データ更新前の値を取得 2.トランザクションの開始 3.データ更新 4.データ更新前の値とデータ更新後の値を比較して、   差分がある場合は確認メッセージを表示する。 5.確認メッセージで「はい」がクリックされた場合はコミットする。 6.確認メッセージで「いいえ」がクリックされた場合はロールバックする。 実装方法はどのようでも構いません。 どなたかご教授ください。

  • オフライン中のトランザクションについて

    表領域をオフラインにした場合、オフライン前に開始されたトランザクションは有効ですが、オフラインのまま、コミット、または、ロールバックして、表領域をオンラインにしても、整合がとれるのはなぜなのでしょうか。 コミットするか、ロールバックするかの情報はどこに保持してるのか疑問です。 (オフラインにしてから、ファイルをリネームし、 トランザクションをロールバックして、 ログをアーカイブし、DB再起動後に、ファイル名を戻して、 オンラインにすると、ちゃんとロールバックされています。 同じ操作で、コミットするとちゃんとコミットされています。 知っている方には当然なのでしょうが、私にとっては、不思議です) 詳しい方がみえましたらご教授お願いいたします。

  • なぜtry{}catch(){}の中?

    DBへの更新を行う際に 私は try{ トランザクションスタート 処理 コミット }catch(Exception e){ ロールバック } の書き方をしていますが トランザクションスタート try{ 処理 コミット }catch(Exception e){ ロールバック } の書き方をしている人がいたので try{}catch(){}の中に トランザクションスタートを入れて下さいと伝えたところ なぜ?try{}catch(){}の中に入れるのか聞かれたのですが 答えられませんでした。 ネットにて色々なソースコードをみても try{}catch(){}の中に書かれているのでそういうモノとして 覚えているのですが、なぜ中なのでしょうか?

    • ベストアンサー
    • PHP
  • トランザクションとlast_insert_id

    トランザクション中にinsertする予定のテーブル(未コミット)のauto_increment値を取得することはできるのでしょうか。 以下のような処理を期待しているのですが、hoge1テーブルのauto_increment値が取得できずに困っております。last_insert_id に関わらず、hoge1テーブルのauto_increment値が取得できる方法があれば教えてください。 (1) トランザクション開始 (2) $sql=" INSERT INTO hoge1(name) value('あああ'); "; (3) ( ロールバック ) (4) $key=mysql_insert_id(); (5) $sql2=" INSERT INTO hoge2(hoge1_primary,age) value($key,'20歳'); "; (6) ( ロールバック ) (7) コミット (8) トランザクション終了 よろしくお願いします。 環境: php5,mysql5 (InnoDB)

    • ベストアンサー
    • MySQL
  • カーソルエラー

    カーソルエラーについて質問です。 phpからpearを使ってoracleへ接続しています。 バッチ処理で大量にSQL文(SELECT,INSERT,UPDATE)を発行したいのですが、カーソルエラーになってしまいます。 途中の処理でエラーになった場合はロールバックしたい為最後までコミットできません。また、なるべく少ないSQL発行で済むようにプログラムを組み替え済みです。 で、少々手詰まりといった状況なのですが、コミットする以外でカーソルエラーを回避する方法はあるでしょうか? DB設計から見直さないとだめですかね…。

    • 締切済み
    • PHP
  • トランザクションのネストについて

    トランザクションのネストについて お世話になります。 今、ストアドの中でストアドを実行するようなSQLを作成しているのですが、 このときのトランザクション処理について教えていただきたいです。 簡単な流れとしましては Aトランザクション開始(大枠のストアド) ↓ 処理a  ↓  Bトランザクション開始  ↓  (Aストアドの中のストアド実行)  ↓  Bコミット  ↓ 処理b ↓ Aコミット といった感じなのですが、BストアドでコミットするとBストアドをCALLする前の処理aが コミットされてしまいます。 ここはBはBだけでコミットされてほしいのです。 独自で調べた限りでは、「トランザクションのネストはMySQLではできない」ということらしいのですが、 こういった場合、どのようにしたらよいのでしょうか。 もし方法があれば、ご教示のほどお願い致します。 -環境- [DB MySQL 5.0] [OS Windows XP]

    • ベストアンサー
    • MySQL
  • accessで画面で更新した内容を全て元に戻す方法

    access初心者です(access2003使用)。 フォームのレコードソースにクエリを指定して詳細部分に条件に一致するレコード内容を一覧形式で表示しています。 一覧ではある項目だけ修正可能としており、フォームの仕様として全てを更新するか全てを更新しないかの二択です。 全てを更新するに関しては修正項目で入力すると自動的(?)にテーブルが更新されており、ある意味何も考慮不要に見えますが、全てを更新しないに関してはどのように行ったらよいか分かっていません。 (イメージとしてフォーム開いたときにトランザクション開始し、フォーム閉じるときにコミット又はロールバックするです。) アドバイスよろしくお願いします。

  • ロールバックとロールフォワード(データベーススペシャリスト試験)

      t0  t1  t2   t3   t4   t5         |           | A s---e  |           |         |           | B s-------------e       |         |           | C s------------------------|         |           | D       |   s----e   |         |           | E       |   s---------| 図がずれていたらごめんなさい。 A~Eはトランザクション sはトランザクション開始 eはコミット t0~t5は時間を表していて 時間t2でチェックポイント 時間t5で障害が発生したとします。 参考書によると復旧時に CとEはロールバックを行い、 BとDはロールフォワードを行うとあります。 B、C、Dはわかるのですが Eにロールバックが必要な理由がわかりません Eを再び実行するためにはデータは トランザクションを開始したt3時点の状態であればよいはずです。 そしてチェックポイント(=t2)の状態はt3と同じなので、 Eの更新前ファイルを使ってデータをロールバックする必要はないように思えます。 どこで間違っているでしょうか。。。

  • C# トランザクション処理

    DataSetのTableAdapterでSQL Serverへのデータ挿入、更新、削除を行います。 try { ta.UpdataQuery(.....); } catche { Exception; } といった処理をしますが、トランザクション処理をする場合、 try { // トランザクション開始 ta.UpdataQuery(.....); // コミット } catche { // ロールバック Exception; } といった感じになるかと思いますが、どのようにコードを書けばよいのでしょうか?手元にコードがありませんので詳細が書けませんが、よろしくお願いします。