DirectoOracleAccessを使ったOracleデータベースの更新を行います。

それでは今度は、データベースの更新を行う方法について説明します。DOA(Direct Oracle Access)のTOracleDataSetコンポーネントで取得したデータセットを更新可能にするためには、ひとつだけコツがあります。それは…

  • SELECT文において、更新対象テーブルのROWID列を取得すること! なのです。
    実際に先ほどのサンプルプログラムを改良して、EMPテーブルを更新可能にするには、以下のようにOracleDataSetのSQLプロパティを変更するだけです。
  OracleDataSet1.SQL = 'SELECT ROWID, EMP.* FROM EMP'

上記のように変更してプログラムを実行すると、データの編集が可能になり、グリッド上のデータの変更が実際のテーブルに反映されるようになります。UPDATE文は、Direct Oracle Access によって自動的に生成されるため、UPDATE文をコーディングする必要は一切ありません。

★ちょっと詳細:DOAによるSQL生成と、レコードロックの制御

TOracleDataSetのDebugプロパティをTrueにして実行すると、DOAが自動生成するSQL文をポップアップ画面で確認できるようになります。

例えば、実際にEMPテーブルをグリッド表示させて、あるレコードのあるフィールド()を書き換える場合は、以下の順番でSQLが発行されます。複数のユーザが同時利用するデータベースアプリケーションを作るにあたっては、同一レコードへの多重アクセスの可能性を考慮に入れた慎重なコーディングが必要になりますが、DOAがその辺の面倒をみてくれています。レコードロックをかけるタイミングはTOracleDataSetのLockingModeプロパティで適切に変更が可能です。

まず、グリッドに表示するデータを取得するSELECT文が実行されます
ここで、グリッド上のあるレコードにカーソルをあわせ、キーボードから文字「M」を入力して編集を開始したとします
編集を開始するにあたり、その一行のみに関するSELECT文が実行されます。先ほどのSELECT文が実行されてから編集開始までの間に、他のユーザがこのレコードをすでに更新していたら、その変更を現在のデータセットに反映します。また、排他ロックがかっていれば、ここで例外を発生させます。(Lockmode=CheckImmediate)
以下のようにSMITH氏のJOBを"MANAGER"に変更して、下矢印キーなどでカーソルを別のレコードに移すと、データの更新が行われます
DOAが内部的にセーブポイントを設定します
DOAは更新に先立ってレコードにロックをかけます。他のユーザに先をこされていたら、先ほどのセーブポイントまでロールバックします。
ここで実際のレコードの更新が行われます。ロックはすでにかかっているので、このステップに入ってから更新が失敗することは(ハードウェア/ネットワーク/OSに障害でもないかぎり)ありません。

上記の例は、OracleDataSet1.LockingMode = lmCheckImmediateの場合でしたが、他の値も設定可能です

lmLockImmediateにすると、エディット開始時に排他レコードロックをかけに行きます。したがって、ロックがかかる期間が長くなりますが、同一レコードについて複数ユーザが編集作業をすることは起こりえなくなり、オンラインアプリケーションでは時として有効なモードです。

lmLockDelayedにすると、エディット開始時のSELECTが省略されます。

lmLockNodeにすると、何のチェックも行われず、直接UPDATE文が実行されます。