レコードセット: パラメーターを利用したレコードセット (ODBC)
このトピックの内容は、MFC ODBC クラスに該当します。
計算したか、エンド ユーザーから入手した情報を利用し、実行時、レコードを選択できると便利なことがあります。 その目標を達成できるのがレコードセット パラメーターです。
このトピックでは、次の内容について説明します。
パラメーター化されたレコードセット
レコードセットをパラメーター化すると、実行時にパラメーター情報を渡すことができます。 これには 2 つの重要な効果があります。
結果的に、実行速度が上がることがあります。
ユーザーから入手したか、実行時に計算された情報など、デザイン時に利用できなかった情報に基づいて、実行時にクエリを構築できます。
Open
を呼び出し、クエリを実行すると、レコードセットによりパラメーター情報が使用され、その SQL SELECT ステートメントが実行されます。 あらゆるレコードセットをパラメーター化できます。
パラメーターを使用するタイミング
パラメーターの典型的な用途:
事前定義されたクエリに実行時引数を渡します。
ストアド プロシージャにパラメーターを渡すには、
Open
を呼び出すとき、パラメーター プレースホルダーを利用して完全なカスタム ODBC CALL ステートメントを指定し、レコードセットの既定の SQL ステートメントをオーバーライドする必要があります。 詳細については、「クラス ライブラリ リファレンス」の「CRecordset::Open」と、「SQL: レコードセットの SQL ステートメントのカスタマイズ (ODBC)」、「レコードセット: 定義済みクエリを利用したクラスの宣言 (ODBC)」を参照してください。さまざまなパラメーター情報を利用し、さまざまなクエリを効率的に実行します。
たとえば、エンド ユーザーが学生登録データベースで特定の学生の情報を探すたびに、ユーザーから入手されるパラメーターとして、その学生の名前または ID を指定できます。 その後、レコードセットの
Requery
メンバー関数を呼び出すと、クリエによってその学生のレコードだけが選択されます。m_strFilter
に保存されている、レコードセットのフィルター文字列は次のようになります。"StudentID = ?"
変数
strInputID
で学生 ID を取得するとします。 パラメーターを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)」を参照してください。
レコードセット クラスのパラメーター化
Note
このセクションの内容は、バルク行フェッチが実装されていない CRecordset
の派生オブジェクトを対象にしています。 バルク行フェッチを使用している場合、パラメーターの実装は同じようなプロセスになります。 詳細については、「レコードセット: バルク行フェッチ (ODBC)」を参照してください。
レコードセット クラスを作成する前に、必要なパラメーター、そのデータの型、それらをレコードセットで使用する方法を決定します。
レコードセット クラスをパラメーター化するには
Note
MFC ODBC コンシューマー ウィザードは、Visual Studio 2019 以降では利用できません。 引き続きこの機能を手動で作成できます。
[クラスの追加] から 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 呼び出しを置きます。
pFX->SetFieldType( CFieldExchange::param ); // RFX calls for parameter data members
レコードセット クラスのコンストラクターで、パラメーター
m_nParams
のカウントをインクリメントします。詳細については、「レコード フィールド エクスチェンジ: ウィザード コードの操作」を参照してください。
このクラスのレコードセット オブジェクトを作成するコードを記述するとき、パラメーターを置換する SQL ステートメント文字列内の各場所に "?" (疑問符) 記号を置きます。
実行時に、渡したパラメーター値が "?" プレースホルダーに順番に入ります。 SetFieldType 呼び出し後の最初のパラメーター データ メンバーが SQL 文字列の最初の "?" に、2 番目のパラメーター データ メンバーが SQL 文字列の 2 番目の "?" に取って代わります。
Note
パラメーターの順序が重要: DoFieldExchange
関数におけるパラメーターの RFX 呼び出しの順序は、SQL 文字列におけるパラメーター プレースホルダーの順序に一致する必要があります。
ヒント
使用する可能性が最も高い文字列はクラスの m_strFilter データ メンバーに指定する文字列ですが (あるとすれば)、一部の ODBC ドライバーでは他の SQL 句でパラメーターが許可されることがあります。
実行時にパラメーター値を渡す
Open
(新しいレコードセット オブジェクトの場合) または Requery
(既存のレコードセット オブジェクトの場合) を呼び出す前にパラメーター値を指定する必要があります。
実行時、レコードセット オブジェクトにパラメーター値を渡すには
レコードセット オブジェクトを構築します。
SQL ステートメントまたはその一部が含まれる、
m_strFilter
文字列など、文字列を用意します。 パラメーター情報が入る場所にプレースホルダーの "?" を置きます。オブジェクトの各パラメーター データ メンバーに実行時パラメーター値を割り当てます。
Open
メンバー関数を呼び出します (既存のレコードセットの場合はRequery
)。
たとえば、実行時に取得した情報を利用し、レコードセットにフィルター文字列を指定するとします。 以前にクラス CStudentSet
のレコードセットを構築しており、その名前が rsStudents
であるとします。これから、ある種類の学生情報を再度問い合わせます。
// 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;
このレコードセットには、実行時パラメーターから構築されたフィルターによって指定された条件をレコードが満たす学生のレコードが含まれます。 この場合、レコードセットにはすべての上級生のレコードが含まれます。
Note
必要であれば、SetParamNull を使用し、パラメーター データ メンバーの値を null に設定できます。 同様に、IsFieldNull を使用し、パラメーター データ メンバーが null であるかどうかを確認できます。
関連項目
レコードセット (ODBC)
レコードセット: レコードの追加、更新、削除 (ODBC)
レコードセット: レコード選択のしくみ (ODBC)