レコードセット : 更新処理の詳細 (ODBC)

更新 : 2007 年 11 月

このトピックの内容は、MFC ODBC クラスに該当します。

このトピックでは、次の内容について説明します。

  • トランザクションなどの操作が更新処理に及ぼす影響

  • 自分の更新処理とほかのユーザーによる更新処理

  • Update および Delete メンバ関数の詳細

ecc2bf09.alert_note(ja-jp,VS.90).gifメモ :

このトピックの内容は、バルク行フェッチが実装されていない CRecordset の派生オブジェクトを対象にしています。バルク行フェッチを実装しているレコードセットには、一部の説明が該当しません。たとえば、AddNewEditDelete、および Update の各メンバ関数を呼び出すことはできません。ただし、トランザクションの処理には支障ありません。バルク行フェッチの詳細については、「レコードセット : バルク行フェッチ (ODBC)」を参照してください。

ほかの操作が更新処理に及ぼす影響

更新処理は、同時に進行しているトランザクションの影響を受けます。トランザクションが終了する前にレコードセットを閉じるか、スクロールすると、トランザクションの影響を受けます。

トランザクションが更新処理に及ぼす影響

AddNewEdit、および Delete の各動作に加え、CDatabaseBeginTransCommitTrans、および Rollback の各メンバ関数と CRecordset の更新関数の連係動作についても理解しておく必要があります。

既定では、AddNewEdit による変更内容は、Update を呼び出した時点でデータ ソースに反映されます。Delete の呼び出しは、すぐに反映されます。しかし、トランザクションを行うと、一連の呼び出しをバッチ処理として実行できます。更新内容は、コミットするまではデータ ソースに反映されません。更新内容を取り消すには、コミットせずに、トランザクションをロールバックします。

トランザクションの詳細については、「トランザクション (ODBC)」を参照してください。

レコードセットを閉じたときの更新処理

トランザクションの実行中に (つまり、CDatabase::CommitTrans または CDatabase::Rollback を呼び出す前に) レコードセットまたはそれに関連付けられた CDatabase オブジェクトを閉じると、(データベースのバック エンドが Microsoft Jet データベース エンジン以外の場合は) トランザクションが自動的にロールバックされます。

ecc2bf09.alert_caution(ja-jp,VS.90).gif注意 :

Microsoft Jet データベース エンジンを使用する場合は、明示的なトランザクションの中でレコードセットを閉じても、このトランザクションをコミットまたはロールバックするまでは、変更した行および配置したロックが解除されません。明示的な Jet トランザクションの内側で開いたレコードセットは、必ずトランザクションの内側で閉じることをお勧めします。また、外側で開いたレコードセットは、必ず外側で閉じることをお勧めします。

スクロールが更新処理に及ぼす影響

レコードセットを レコードセット : スクロール (ODBC) すると、エディット バッファには新しい現在のレコードのフィールド値が格納されます (前のレコードは最初に格納されません)。スクロールによって移動すると、削除されたレコードは飛ばされます (選択されません)。AddNew または Edit の後で、UpdateCommitTrans、または Rollback を呼び出さずにスクロールすると、変更内容はすべて失われ、警告は行われません。新しいレコードがエディット バッファに格納されます。エディット バッファには移動先のレコードの値が格納され、前のレコードの値は捨てられるため、データ ソースは変更されません。この動作は、AddNewEdit の両方で行われます。

自分の更新処理とほかのユーザーによる更新処理

レコードセットを使ってデータを更新すると、ほかのユーザーにも影響を及ぼします。同じように、ほかのユーザーが行った更新処理は、自分が使用中のレコードセットに影響します。

マルチ ユーザー環境では、自分のレコードセットとほかのユーザーのレコードセットが同じレコードを含んでいることがあります。自分が取得する前にレコードに加えられた変更は、自分のレコードセットに反映されます。ダイナセットでは、レコードにスクロールすると、そのたびにレコードが取得されるため、レコードにスクロールするたびに変更内容が反映されます。一方、スナップショットでは、レコードに最初にスクロールしたときにだけレコードが取得されるため、それ以前の変更内容しか反映されません。

自分のレコードセットを開いた後に他のユーザーによって追加されたレコードは、クエリを再実行しない限り、自分のレコードセットには反映されません。自分のレコードセットがダイナセットのときは、ほかのユーザーが既存のレコードに加えた編集結果は、そのレコードに移動 (スクロール) したときに反映されます。自分のレコードセットがスナップショットのときは、クエリを再実行するまで編集結果は反映されません。他のユーザーによって追加または削除されたレコードをスナップショットに反映させる場合や、他のユーザーによって追加されたレコードをダイナセットに反映させる場合は、CRecordset::Requery を呼び出す必要があります。ダイナセットでは、ほかのユーザーによる削除は反映されます。Requery を呼び出すと、自分で追加したレコードを確認することもできます。ただし、自分で行った削除を確認することはできません。

ecc2bf09.alert_note(ja-jp,VS.90).gifヒント :

スナップショット全体を一度にキャッシュするには、スナップショットを開いた直後に MoveLast を呼び出します。次に、MoveFirst を呼び出してレコードセットを操作します。MoveLast は、全レコードをスクロールするのと同じ動作を行いますが、一度に全レコードを取得します。ただし、パフォーマンスが低下する場合があります。また、この機能が必要ないドライバもあります。

同じように、自分の更新処理もほかのユーザーに影響します。

更新処理と削除処理の詳細

ここでは、UpdateDelete の動作について詳しく説明します。

更新の成功と失敗

Update が成功すると、AddNew モードまたは Edit モードが終了します。AddNew モードまたは Edit モードを再開するには、AddNew または Edit を再び呼び出します。

Update が失敗 (FALSE が返るか、例外がスローされる) しても、AddNew モードまたは Edit モードは継続します。失敗した場合は、以下のいずれかの処理を行うことができます。

  • フィールド データ メンバの値を変えて Update を再実行します。

  • AddNew を呼び出してフィールド データ メンバを Null 値にリセットしてから、フィールド データ メンバの値を設定し、Update を再び呼び出します。

  • Edit を呼び出して、AddNew または Edit を呼び出す前のレコードセットの値を再読み込みします。次に、フィールド データ メンバの値を設定し、Update を再び呼び出します。Update が成功すると (AddNew 呼び出しの後を除いて)、フィールド データ メンバには新しい値が設定されます。

  • Move を呼び出して (パラメータとして AFX_MOVE_REFRESH または 0 を渡す場合も)、すべての変更内容を無効にして AddNew モードまたは Edit モードを終了します。

更新と削除

ここで説明する内容は、UpdateDelete の両方が対象です。

Update または Delete の操作では、一度に 1 レコードだけが更新されます。更新されるのは、レコードセットのフィールド データ メンバに値が保存されている現在のレコードです。なんらかの理由により複数のレコードが更新されるか、どのレコードも更新されない場合は、次のどちらかの RETCODE 値を持つ例外がスローされます。

  • AFX_SQL_ERROR_NO_ROWS_AFFECTED

  • AFX_SQL_ERROR_MULTIPLE_ROWS_AFFECTED

これらの例外がスローされても、Update または Delete を呼び出したときの AddNew モードまたは Edit モードは継続します。これらの例外は、通常、以下の場合にスローされます。次の例外が最も頻繁に発生します。

  • AFX_SQL_ERROR_NO_ROWS_AFFECTED。共有ロック モードに設定しているときに、別のユーザーがレコードを変更したために、更新または削除するレコードをフレームワークが識別できなくなった場合。

  • AFX_SQL_ERROR_MULTIPLE_ROWS_AFFECTED。更新しようとしたテーブルに主キーまたは一意なインデックスがなく、レコードセット内の列数が不足していて、テーブルの行を特定できない場合。

参照

概念

レコードセット (ODBC)

レコードセット : レコード選択のしくみ (ODBC)

レコード フィールド エクスチェンジ (RFX)

SQL

例外処理 : データベースの例外