次の方法で共有


レコードセット : AddNew、Edit、Delete の動作のしくみ (ODBC)

更新 : 2007 年 11 月

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

このトピックでは、CRecordset クラスの AddNewEdit、および Delete の各メンバ関数の動作のしくみについて説明します。ここでは、次の内容について説明します。

  • レコード追加のしくみ

  • 追加したレコードの参照可能範囲

  • レコード編集のしくみ

  • レコード削除のしくみ

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

このトピックの内容は、バルク行フェッチが実装されていない CRecordset の派生オブジェクトを対象にしています。バルク行フェッチを使用する場合は、「レコードセット : バルク行フェッチ (ODBC)」を参照してください。

レコード フィールド エクスチェンジ : RFX の動作のしくみ」も参照してください。更新処理における RFX の役割について説明しています。

レコードの追加

レコードセットに新しいレコードを追加するには、レコードセットのメンバ関数 AddNew を呼び出して新しいレコードのフィールド データ メンバ値を設定し、メンバ関数 Update を呼び出してレコードをデータ ソースに書き出します。

AddNew を呼び出すときは、レコードセットを読み取り専用で開かないでください。レコードセットが更新可能かどうかは、CanUpdate メンバ関数および CanAppend メンバ関数で調べます。

AddNew を呼び出すと、次の処理が行われます。

  • エディット バッファ内のレコードが待避されます。これにより、操作を取り消したときに内容を復元できます。

  • 後で変更が加えられたことを確認できるように、フィールド データ メンバにフラグが設定されます。フィールド データ メンバは、クリーンである (変更が加えられていない) ことが示され、値が Null (データベース上で値がないということを表す記号) に設定されます。

AddNew を呼び出した後、エディット バッファは、新しい空のレコードを表しています。このレコードの値を設定するには、エディット バッファの各フィールドに値を直接代入します。具体的なデータ値をフィールドに指定せずに、SetFieldNull を呼び出して Null 値を指定できます。

変更内容をコミットするには、Update を呼び出します。新しいレコードに対して Update を呼び出すと、次の処理が行われます。

  • ODBC API 関数 ::SQLSetPos をサポートしている ODBC ドライバを使っている場合、MFC は、この関数を使ってデータ ソースにレコードを追加します。::SQLSetPos 関数を使用すると、MFC は効率的にレコードを追加できます。これは、SQL ステートメントの構築および処理が必要ないためです。

  • ::SQLSetPos を使えない場合、MFC は以下の処理を行います。

    1. 変更されていない場合、Update は、何もせずに 0 を返します。

    2. 変更されている場合、Update は、SQL INSERT ステートメントを作成します。値が変更されたフィールド データ メンバに対応する列が、INSERT ステートメントによって指定されます。特定の列を強制的に INSERT ステートメントに取り込むには、メンバ関数 SetFieldDirty を呼び出します。

      SetFieldDirty( &m_dataMember, TRUE );
      
    3. Update では、新しいレコードがコミットされます。つまり、トランザクションの進行中以外は、INSERT ステートメントが実行され、新しいレコードがデータ ソース上のテーブル (およびスナップショットがない場合はレコードセット) にコミットされます。

    4. 待避されていたレコードがエディット バッファに復元されます。INSERT ステートメントの成功/失敗に関係なく、AddNew を呼び出す前に現在のレコードであったレコードが再び現在のレコードになります。

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

    新しいレコードを詳細に制御するには、値が必要なすべてのフィールドに値を設定し、値が不要なフィールドには、そのフィールドへのポインタと TRUE に設定されたパラメータ (既定) で SetFieldNull を呼び出して、明示的に Null を設定します。特定のフィールドをデータ ソースに書き出さないようにするには、フィールドへのポインタとパラメータ FALSESetFieldDirty を呼び出して、フィールドの値を変更しないようにします。フィールドの値として NULL を設定できるかどうかを調べるには、IsFieldNullable を呼び出します。

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

    レコードセット データ メンバの値の変更を検出するために、MFC では、レコードセットに格納できる各データ型に適切な PSEUDO_NULL 値を使用しています。既に NULL として印が付けられるフィールドに、明示的に PSEUDO_NULL を設定するには、第 1 パラメータとしてフィールドのアドレス、第 2 パラメータとして FALSE を指定して、関数 SetFieldNull を呼び出します。

追加したレコードの参照可能範囲

レコードセットに追加したレコードは、すぐに使えるようになるとは限りません。レコードの参照可能範囲は、以下の 2 つの条件によって左右されます。

  • ドライバのサポート範囲

  • フレームワークが活用できるドライバの機能

ODBC API 関数 ::SQLSetPos をサポートする ODBC ドライバを使っている場合、MFC はこの関数を使ってレコードを追加します。関数 ::SQLSetPos を使った場合は、追加したレコードは、更新可能なすべての MFC レコードセットからアクセスできるようになります。この関数をサポートしていない場合は、追加されたレコードを参照できません。追加されたレコードを参照するには、Requery を呼び出す必要があります。また、::SQLSetPos を使った場合の方がより効率的です。

既存のレコードの編集

レコードセット内の既存のレコードを編集するには、目的のレコードにスクロールし、メンバ関数 Edit を呼び出します。次に、新しいレコードのフィールド データ メンバの値を設定し、メンバ関数 Update を呼び出してレコードをデータ ソースに書き出します。

Edit を呼び出すときは、レコードセットを更新可能にし、編集するレコードに移動しておきます。レコードセットが更新可能かどうかは、CanUpdate メンバ関数および IsDeleted メンバ関数で調べます。また、現在のレコードが削除されておらず、レコードセット内にレコードが存在している必要があります (IsBOFIsEOF の両方が 0 を返す必要があります)。

Edit を呼び出すと、エディット バッファ内のレコード (現在のレコード) が待避されます。待避されたレコードは、各フィールドが変更されたかどうかを確認するために後で使います。

Edit を呼び出すと、エディット バッファは現在のレコードを指したままですが、フィールド データ メンバを変更できるようになります。レコードを変更するには、フィールド データ メンバの値を直接変更します。具体的なデータ値をフィールドに指定せずに SetFieldNull を呼び出すと、Null 値を指定できます。変更をコミットするには、Update を呼び出します。

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

AddNew モードまたは Edit モードを終了するには、AFX_MOVE_REFRESH パラメータを指定して Move を呼び出します。

Update を呼び出すときは、レコードセットが空でなく、現在のレコードが削除されていないことが必要です。つまり、IsBOFIsEOF、および IsDeleted がすべて 0 を返す必要があります。

編集されたレコードに対して Update を呼び出すと、次の処理が行われます。

  • ODBC API 関数 ::SQLSetPos をサポートしている ODBC ドライバを使っている場合、MFC は、この関数を使ってデータ ソースのレコードを変更します。関数 ::SQLSetPos を使って、ドライバは対応するサーバー上のレコードとエディット バッファを比較し、変更されている場合はサーバー上のレコードを変更します。::SQLSetPos 関数を使用すると、MFC は効率的にレコードを更新できます。これは、SQL ステートメントの構築および処理が必要ないためです。

    または

  • ::SQLSetPos を使えない場合、MFC は以下の処理を行います。

    1. 変更されていない場合、Update は、何もせずに 0 を返します。

    2. 変更されている場合、Update は、SQL UPDATE ステートメントを作成します。値が変更されたフィールド データ メンバに対応する列が、UPDATE ステートメントによって指定されます。

    3. Update が変更をコミットします。つまり、UPDATE ステートメントが実行され、データ ソース上のレコードが変更されます。ただし、トランザクションが進行中の場合はコミットされません。トランザクションが更新に与える影響については、「トランザクション : レコードセットからのトランザクション実行 (ODBC)」を参照してください。ODBC が保持するレコードのコピーも更新されます。

    4. AddNew の場合とは異なり、Edit の処理では、待避したレコードは復元されません。編集後のレコードが現在のレコードになります。

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

    Update を呼び出してレコードセットを更新する前に、テーブルの主キーを構成するすべての列 (または、テーブル上の一意なインデックスを構成するすべての列か、行を一意に識別するのに十分な数の列) がレコードセットに含まれていることに注意してください。場合によっては、フレームワークは、レコードセット内で選択されている列だけに基づいてテーブル内の更新するレコードを特定します。選択されている列数が不足していると、テーブル内の複数のレコードが更新されてしまう場合があります。この場合は、Update を呼び出した結果として例外がスローされます。

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

    AddNew または Edit のいずれかを呼び出した後、Update を呼び出さずに、再びいずれかの関数を呼び出すと、エディット バッファが再表示され、待避しておいたレコードの値に戻ります。つまり、AddNew または Edit を中止してやり直すことができます。編集中のレコードが間違っていることに気付いたときは、再び AddNew または Edit を呼び出してやり直せます。

レコードの削除

レコードセットのレコードを削除するには、目的のレコードにスクロールし、レコードセットのメンバ関数 Delete を呼び出します。AddNew および Edit の場合とは異なり、Delete の後は Update を呼び出す必要がありません。

Delete を呼び出すときは、レコードセットを更新可能にし、削除するレコードに移動しておきます。メンバ関数 CanUpdateIsBOFIsEOF、および IsDeleted によってこれらの状態をチェックできます。

Delete を呼び出すと、次の処理が行われます。

  • ODBC API 関数 ::SQLSetPos をサポートしている ODBC ドライバを使っている場合、MFC は、この関数を使ってデータ ソースのレコードを削除します。関数 ::SQLSetPos を使うと、MFC が効率的にレコードを削除できます。これは、SQL ステートメントの構築、実行が必要ないためです。

    または

  • ::SQLSetPos を使えない場合、MFC は以下の処理を行います。

    1. AddNew および Edit の場合と同様に、エディット バッファ内の現在のレコードはバックアップされません。

    2. Delete では、レコードを削除する SQL DELETE ステートメントを作成します。

      AddNew および Edit の場合とは異なり、エディット バッファの現在のレコードは格納されません。

    3. DELETE ステートメントが実行されます。データ ソース上のレコードに、削除されたことを示す印が付けられます。また、レコードセットがスナップショットの場合は、ODBC 上のレコードにも削除の印が付けられます。

    4. 削除されたレコードの値はレコードセットのフィールド データ メンバ上に残っていますが、フィールド データ メンバには Null であることを表す印が付けられています。したがって、レコードセットの IsDeleted メンバ関数は 0 以外の値を返します。

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

    レコードを削除したら、別のレコードにスクロールして、エディット バッファの値を新しいレコードの値にする必要があります。Delete を再度呼び出すか、Edit を呼び出すと、エラーが発生します。

更新処理で使用する SQL ステートメントについては、「SQL」を参照してください。

参照

概念

レコードセット (ODBC)

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

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