いつもおわせになっております
環境:Delphi2007 DB-Oracle10g
ADOでレコードを削除した時に
「行が見つからなかっため、更新できません。列の値は最後に読み込まれた後で変更された可能性があります。」
とエラーがでます。
色々と調べてみましたが、有効な事例にいきつきませんでした。
処理としては、
TADOQuery.Deleteしたものを
TADOQuery.UpdateBatch(arAll)でデータベースに更新かけています。
TADOQueryのLockTypeはltBatchOptimisticです。
エラーの発生するタイミングは、
TADOQuery.UpdateBatch(arAll)を実行した時です。
レコードの追加、変更は正常に実行されます。
追記
三つのテーブルを結合したSELECT文で必要なデータを抽出しています。
こちらに間違いがあるのかも知れません。
select j.*
from m_joint_bmp j,
m_koumoku mei,
m_koumoku joi
where ((j.keijyo_kbn = :keijyo_kbn
and j.keijyo_code = :keijyo_code
and j.meisyo_kbn = :meisyo_kbn
and j.meisyo_code = :meisyo_code)
or (j.keijyo_kbn = :keijyo_kbn2
and j.keijyo_code = :keijyo_code2))
and j.meisyo_kbn = mei.koumoku_kbn(+)
and j.meisyo_code = mei.koumoku_code(+)
and j.joint_type_kbn = joi.koumoku_kbn(+)
and j.joint_type_code = joi.koumoku_code(+)
order by mei.koumoku_jun,
joi.koumoku_jun
For Update Nowait
条件に合うレコードが無いのでしょう。
>TADOQuery.Deleteしたものを
で削除したのではないでしょうか?
HOtaさん、ありがとうございます。
抽出したレコードが格納されたデータセットに対して、削除したい行に
カーソルを位置付けてから、Deleteを発行しているので条件に合うレコードがないということはないの思うのですが。
LockTypeをltBatchOptimisticに設定していることで、サーバーへの直接更新ではなく、キャッシュへの更新に切り替わっていると解釈しています。
なので、キャッシュにて削除するレコードがマークされ、UpdateBatchメソッドを呼び出したときに実際に削除されると考えているのですが、どうでしょうか?
ご指摘の意味を取り違えていたらすみません。
追記
SQLを少し変更してみました。
select j.*
from m_joint_bmp j,
m_koumoku joi
where ((j.keijyo_kbn = :keijyo_kbn
and j.keijyo_code = :keijyo_code
and j.meisyo_kbn = :meisyo_kbn
and j.meisyo_code = :meisyo_code)
or (j.keijyo_kbn = :keijyo_kbn2
and j.keijyo_code = :keijyo_code2))
and j.joint_type_kbn = joi.koumoku_kbn
and j.joint_type_code = joi.koumoku_code
order by joi.koumoku_jun
For Update Nowait
mei.koumoku_junでのソートを削りました。
要するにテーブルの結合を三つから二つにしたところ、
正常に削除できました。
ADOというよりは単純にSQLが問題のようです。
タイトルとは異なるところに質問になってしまいすみません。
UpdateBatchの直前に、レコードがあるか検査してみればどうでしょうか?
HOtaさん、ありがとうございます。
>UpdateBatchの直前に、レコードがあるか検査してみればどうでしょうか?
TADOQueryからはレコードが削除された状態でした。
サーバーには更新されていません。
どうやら三つのテーブルを結合していることor
自己結合を利用していることが起因しているようです。
>from m_joint_bmp j,
m_koumoku mei,
m_koumoku joi
苦しい対策ですが、データ更新用のTADOQueryを生成し
データ表示用のTADOQueryと同じ処理を行いました。
※データ更新用のTADOQueryは単一テーブルに更新をかけるものです。
BDEのTQueryには、TUpdateSQLというのがあり、結合したテーブルの更新用に使用するようになっていました。
HOtaさん、ありがとうございます。
返事が遅くなってしまいました。
>BDEのTQueryには、TUpdateSQLというのがあり、結合したテーブルの更新用に使用するようになっていました。
確かにBDEならば、TUpdateSQLを利用すれば解決しそうですね。
今回はADOとの仕様なので前回までの処理で対応したいと思います。
ありがとうございました。
ツイート | ![]() |