レコードセット : パラメータを利用したレコードセット (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 値に設定します。
ヒント : パラメータを使用すると、単にフィルタを使用するより効率的です。パラメータを使ったレコードセットでは、SQL SELECT ステートメントを作成するのは 1 回で済みます。パラメータ化されていないフィルタを使ったレコードセットでは、新しいフィルタ値を設定して Requery を呼び出すたびに、SELECT ステートメントを作成する必要があります。
フィルタの詳細については、「レコードセット : レコードのフィルタ処理 (ODBC)」を参照してください。
パラメータを利用したレコードセット クラスの作成
メモ : |
---|
ここで説明する内容は、バルク行フェッチが実装されていない CRecordset の派生オブジェクトを対象にしています。バルク行フェッチを使用するレコードセットでも、パラメータを実装する方法は基本的に同じです。詳細については、「レコードセット : バルク行フェッチ (ODBC)」を参照してください。 |
レコードセット クラスを作成する前に、どのパラメータが必要か、パラメータのデータ型を何にするか、パラメータをどのように利用するかを決める必要があります。
パラメータを利用したレコードセット クラスを作成するには
クラスの追加の MFC ODBC コンシューマ ウィザード を実行して、クラスを作成します。
レコードセットの列に対応するフィールド データ メンバを指定します。
ウィザードがプロジェクト内のファイルにクラスを出力したら、その .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" を付けます。
.cpp ファイル内の DoFieldExchange メンバ関数定義に変更を加えます。追加したパラメータ データ メンバごとに RFX 関数呼び出しを追加します。RFX 関数の記述方法については、「レコード フィールド エクスチェンジ : RFX の動作のしくみ」を参照してください。すべてのパラメータに対する RFX 呼び出しの前に、次の関数呼び出しを 1 回だけ行います。
pFX->SetFieldType( CFieldExchange::param ); // RFX calls for parameter data members
レコードセット クラスのコンストラクタで、m_nParams のパラメータ数をインクリメントします。
詳細については、「レコード フィールド エクスチェンジ : ウィザード コードの操作」を参照してください。
このクラスのレコードセット オブジェクトを作成するコードを記述する場合は、SQL ステートメントの文字列の、パラメータ値に置き換える箇所に、プレースホルダとして "?" (疑問符) を配置します。
プレースホルダは、実行時に、パラメータ値に順番に置き換えられます。SetFieldType 呼び出しの後で設定した最初のパラメータ データ メンバは、SQL 文字列の最初の "?" プレースホルダと置き換わります。以降のパラメータと "?" プレースホルダも同じように置き換わります。
メモ : |
---|
パラメータの順序は重要です。DoFieldExchange 関数のパラメータに対する RFX 呼び出しの順序は、SQL 文字列のパラメータ プレースホルダの順序に一致させる必要があります。 |
ヒント : |
---|
最も多く使用される文字列は、クラスの m_strFilter データ メンバに指定した文字列ですが、ODBC ドライバによっては、他の SQL 句のパラメータも使用できます。 |
実行時にパラメータ値を渡す方法
パラメータ値は、メンバ関数 Open (新規作成したレコード オブジェクトの場合) またはメンバ関数 Requery (既存のオブジェクトを再利用する場合) を呼び出す前に設定します。
パラメータの値を実行時にレコードセット オブジェクトに渡すには
レコードセット オブジェクトを構築します。
m_strFilter など、SQL ステートメント (またはその一部) を含む文字列を 1 つ以上用意します。後でパラメータ値を代入するプレースホルダには "?" を書いておきます。
実行時にパラメータ データ メンバに値を代入します。
メンバ関数 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;
これにより、レコードセットには、実行時にパラメータによって指定されたフィルタ条件に合致するレコードだけが格納されます。この場合、レコードセットには上級生のレコードだけが格納されます。
メモ : |
---|
必要に応じて、SetParamNull を使用して、パラメータ データ メンバの値を Null に設定することもできます。パラメータ データ メンバの値が NULL かどうかを調べるには IsFieldNull を使います。 |