レコードセット : パラメータを利用したレコードセット (ODBC)

更新 : 2007 年 11 月

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

場合によっては、ユーザー入力または計算結果に応じて実行時にレコードを選択できるようにする必要があります。このような場合は、レコードセット パラメータを使います。

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

  • レコードセットをパラメータ化する目的

  • レコードセットをパラメータ化するタイミングと理由

  • レコードセット クラスでパラメータ データ メンバを宣言する方法

  • パラメータの情報を実行時にレコードセット オブジェクトに渡す方法

パラメータを利用したレコードセット

パラメータ化したレコードセットでは、実行時にパラメータ値を渡すことができます。これには、次の 2 つの利点があります。

  • 実行速度を向上できます。

  • デザイン時に得られない情報 (実行時のユーザー入力や計算結果など) に基づき、実行時にクエリを構成できます。

Open を呼び出してクエリを実行すると、パラメータの値を使って SQL SELECT ステートメントが作成されます。どのレコードセットでもパラメータを使用できます。

パラメータを使用する状況

通常、パラメータは以下の場合に使います。

  • 定義済みのクエリに実行時の引数を渡す場合

    ストアド プロシージャにパラメータを渡すには、完全なカスタム ODBC CALL ステートメントを渡します。つまり、Open を呼び出すときに、パラメータ プレースホルダ付きの完全なカスタム ODBC CALL ステートメントを指定して、レコードセットの既定の SQL ステートメントをオーバーライドします。詳細については、『MFC リファレンス』の「CRecordset::Open」、および「SQL : レコードセットの SQL ステートメントのカスタマイズ (ODBC)」と「レコードセット : 定義済みクエリを利用したクラスの宣言 (ODBC)」を参照してください。

  • そのつどパラメータ情報を変更して、クエリを繰り返し実行する場合

    たとえば、学生の登録情報データベースを検索して特定の学生の情報を検索するたびに、学生の氏名または ID パラメータに、ユーザーが値を入力できるようにします。レコードセットのメンバ関数 Requery を呼び出すと、指定された学生のレコードだけが選択されます。

    m_StrFilter に保持するレコードセット フィルタ文字列は、次のように設定します。

    "StudentID = ?"
    

    学生の ID を変数 strInputID に格納するとします。strInputID に学生 ID の値として 100 を代入すると、この変数の値は、フィルタ文字列内の "?" で示されるパラメータ プレースホルダに結び付けられます。

    パラメータ値を次のように代入します。

    strInputID = "100";
    ...
    m_strParam = strInputID;
    

    フィルタ文字列は、次のように設定しないでください。

    m_strFilter = "StudentID = 100";   // 100 is incorrectly quoted
                                       // for some drivers
    

    フィルタ文字列の引用符の使い方については、「レコードセット : レコードのフィルタ処理 (ODBC)」を参照してください。

    クエリを再実行するたびに、パラメータの値を新しい ID 値に設定します。

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

    パラメータを使用すると、単にフィルタを使用するより効率的です。パラメータを使ったレコードセットでは、SQL SELECT ステートメントを作成するのは 1 回で済みます。パラメータ化されていないフィルタを使ったレコードセットでは、新しいフィルタ値を設定して Requery を呼び出すたびに、SELECT ステートメントを作成する必要があります。

フィルタの詳細については、「レコードセット : レコードのフィルタ処理 (ODBC)」を参照してください。

パラメータを利用したレコードセット クラスの作成

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

ここで説明する内容は、バルク行フェッチが実装されていない CRecordset の派生オブジェクトを対象にしています。バルク行フェッチを使用するレコードセットでも、パラメータを実装する方法は基本的に同じです。詳細については、「レコードセット : バルク行フェッチ (ODBC)」を参照してください。

レコードセット クラスを作成する前に、どのパラメータが必要か、パラメータのデータ型を何にするか、パラメータをどのように利用するかを決める必要があります。

パラメータを利用したレコードセット クラスを作成するには

  1. クラスの追加の MFC ODBC コンシューマ ウィザード を実行して、クラスを作成します。

  2. レコードセットの列に対応するフィールド データ メンバを指定します。

  3. ウィザードがプロジェクト内のファイルにクラスを出力したら、その .h ファイルを編集してクラス宣言に 1 つ以上のパラメータ データ メンバを直接書き込みます。このようにしてパラメータを追加したスナップショット クラスの例を次に示します。この例では、"上級生を選択せよ" というクエリを作成します。

    class CStudentSet : public CRecordset
    {
    // Field/Param Data
        CString m_strFirstName;
        CString m_strLastName;
        CString m_strStudentID;
        CString m_strGradYear;
    
        CString m_strGradYrParam;
    };
    

    ウィザードによって生成されるフィールド データ メンバの後にパラメータ データ メンバを追加します。命名規約として、ユーザー定義のパラメータ名の末尾には "Param" を付けます。

  4. .cpp ファイル内の DoFieldExchange メンバ関数定義に変更を加えます。追加したパラメータ データ メンバごとに RFX 関数呼び出しを追加します。RFX 関数の記述方法については、「レコード フィールド エクスチェンジ : RFX の動作のしくみ」を参照してください。すべてのパラメータに対する RFX 呼び出しの前に、次の関数呼び出しを 1 回だけ行います。

    pFX->SetFieldType( CFieldExchange::param );
    // RFX calls for parameter data members
    
  5. レコードセット クラスのコンストラクタで、m_nParams のパラメータ数をインクリメントします。

    詳細については、「レコード フィールド エクスチェンジ : ウィザード コードの操作」を参照してください。

  6. このクラスのレコードセット オブジェクトを作成するコードを記述する場合は、SQL ステートメントの文字列の、パラメータ値に置き換える箇所に、プレースホルダとして "?" (疑問符) を配置します。

    プレースホルダは、実行時に、パラメータ値に順番に置き換えられます。SetFieldType 呼び出しの後で設定した最初のパラメータ データ メンバは、SQL 文字列の最初の "?" プレースホルダと置き換わります。以降のパラメータと "?" プレースホルダも同じように置き換わります。

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

パラメータの順序は重要です。DoFieldExchange 関数のパラメータに対する RFX 呼び出しの順序は、SQL 文字列のパラメータ プレースホルダの順序に一致させる必要があります。

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

最も多く使用される文字列は、クラスの m_strFilter データ メンバに指定した文字列ですが、ODBC ドライバによっては、他の SQL 句のパラメータも使用できます。

実行時にパラメータ値を渡す方法

パラメータ値は、メンバ関数 Open (新規作成したレコード オブジェクトの場合) またはメンバ関数 Requery (既存のオブジェクトを再利用する場合) を呼び出す前に設定します。

パラメータの値を実行時にレコードセット オブジェクトに渡すには

  1. レコードセット オブジェクトを構築します。

  2. m_strFilter など、SQL ステートメント (またはその一部) を含む文字列を 1 つ以上用意します。後でパラメータ値を代入するプレースホルダには "?" を書いておきます。

  3. 実行時にパラメータ データ メンバに値を代入します。

  4. メンバ関数 Open を呼び出します。既存のレコードセットを再利用する場合は Requery を呼び出します。

たとえば、実行時に得られたデータに基づきフィルタ文字列を作成する場合を考えてみます。CStudentSet クラスのレコードセット rsStudent が既に生成されている場合は、次のクエリを再実行して特定の情報を取得できます。

// Set up a filter string with 
// parameter placeholders
rsStudents.m_strFilter = "GradYear <= ?";

// Obtain or calculate parameter values 
// to pass--simply assigned here 
CString strGradYear = GetCurrentAcademicYear( );

// Assign the values to parameter data members
rsStudents.m_strGradYrParam = strGradYear;

// Run the query
if( !rsStudents.Requery( ) )
    return FALSE;

これにより、レコードセットには、実行時にパラメータによって指定されたフィルタ条件に合致するレコードだけが格納されます。この場合、レコードセットには上級生のレコードだけが格納されます。

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

必要に応じて、SetParamNull を使用して、パラメータ データ メンバの値を Null に設定することもできます。パラメータ データ メンバの値が NULL かどうかを調べるには IsFieldNull を使います。

参照

概念

レコードセット (ODBC)

レコードセット : レコードの追加、更新、削除 (ODBC)

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