SQL: レコードセットの SQL ’ ステートメントのカスタマイズ (ODBC)

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

  • フレームワークが新しいステートメントを構築SQL方法

  • SQL ステートメントをオーバーライドする方法

Note

この情報は、MFC ODBC クラスに該当します。 MFC DAO クラスを使用している場合は、「DAO ヘルプ」の「Microsoft Jet データベース エンジン SQL と ANSI SQLの比較」を参照してください。

SQL ステートメントの構築

レコードセットのレコード選択は、主に SELECT ステートメントSQL基に設定されます。 ウィザードを使用してクラスを宣言すると、次のようなメンバー関数のオーバーライドバージョンが書き込まれます (というレコードセット クラス GetDefaultSQL の場合 CAuthors )。

CString CAuthors::GetDefaultSQL()
{
    return "AUTHORS";
}

既定では、このオーバーライドは、ウィザードで指定したテーブル名を返します。 この例では、テーブル名は "AUTHORS" です。後でレコードセットのメンバー関数を呼び Open 出す際に、 Open フォームの最終的な Open ステートメントを構築します。

SELECT rfx-field-list FROM table-name [WHERE m_strFilter]
       [ORDER BY m_strSort]

ここで table-name 、 は を呼び出すことによって GetDefaultSQL 取得 rfx-field-list され、 の RFX 関数呼び出しから取得されます DoFieldExchange 。 これは、実行時にオーバーライドするバージョンに置き換える場合を限り 、SELECT ステートメントに対して取得しますが、パラメーターまたはフィルターを使用して既定のステートメントを変更することもできます。

Note

スペースを含む (または含まれる可能性がある) 列名を指定する場合は、名前を角かっこで囲む必要があります。 たとえば、名前 "First Name" は "[First Name]" である必要があります。

既定の SELECT ステートメント をオーバーライド するには、 を呼び出す際に、完全な SELECT ステートメントを含む文字列を渡します 。 レコードセットでは、独自の既定の文字列を作成する代わりに、指定した文字列を使用します。 置換ステートメントに WHERE 句が含まれている場合は、2 つのフィルター ステートメントが含まれるため、 でフィルター を指定しない必要があります。 同様に、置換ステートメントに ORDER BY 句が含まれている場合は、 で並べ替えを指定し、2 つの並べ替えステートメントが 含まれるのを確認してください。

Note

フィルター (または SQL ステートメントの他の部分) でリテラル文字列を使用する場合は、DBMS 固有のリテラル プレフィックスとリテラル サフィックス文字 (または文字) を使用して、このような文字列を "引用符" (指定した区切り記号で囲む) 必要がある場合があります。

DBMS によっては、外部結合などの操作に関する特別な構文要件が発生する場合があります。 ODBC 関数を使用して、DBMS 用のドライバーからこの情報を取得します。 たとえば、 などの特定のデータ型に対して を呼び出して、特定の文字LITERAL_PREFIX ::SQLGetTypeInfoSQL_VARCHAR 要求LITERAL_SUFFIXします。 データベースに依存しないコードを記述する場合は、構文の詳細については、「ODBCプログラマー リファレンス」の「付録C: SQL Grammar」を参照してください。

レコードセット オブジェクトは、カスタムSQL渡す場合を含め、レコードの選択に使用する SQLします。 この方法は、主にメンバー関数の lpszSQL パラメーターに渡す値によって 異なります。

SELECT ステートメントの一般的な形式SQLに示します。

SELECT [ALL | DISTINCT] column-list FROM table-list
    [WHERE search-condition][ORDER BY column-list [ASC | DESC]]

レコードセットの SQL ステートメントにDISTINCTキーワードを追加する方法の 1 つは、 の最初の RFX 関数呼び出しに キーワードを埋め込む方法です 。 次に例を示します。

...
    RFX_Text(pFX, "DISTINCT CourseID", m_strCourseID);
...

注意

この手法は、読み取り専用として開いたレコードセットでのみ使用します。

SQL ステートメントのオーバーライド

次の表は、 への lpszSQL パラメーターの可能性を示 しています 。 表のケースについては、次の表で説明します。

lpszSQL パラメーターと結果のSQL文字列

ケース lpszSQL で渡す情報 結果の SELECT ステートメント
1 NULL SELECTrfx-field-listFROMtable-name

CRecordset::Open を呼 GetDefaultSQL び出してテーブル名を取得します。 結果の文字列は、返される内容に応じて、ケース 2 から 5 GetDefaultSQL の 1 つになります。
2 テーブル名 SELECTrfx-field-listFROMtable-name

フィールド リストは、 の RFX ステートメントから取得されます DoFieldExchange 。 と m_strFilterm_strSort 空ではない場合は m_strFilter 句や m_strSort 追加します。
3 * WHERE 句またはORDER BY 句を含完全なSELECT ステートメント 渡された 。 と m_strFilterm_strSort 空ではない場合は m_strFilter 句や m_strSort 追加します。
4 * WHEREまたは ORDER BY 句を含む完全な SELECT ステートメント 渡された 。 m_strFilter や は空のままにする必要があります。または、2 m_strSort つのフィルターステートメントや並べ替えステートメントが生成されます。
5 * ストアド プロシージャの呼び出し 渡された 。

* m_nFields は * ステートメントで指定された列数以下である必要があります。 SELECTステートメントで指定する各列のデータ型は、対応する RFX 出力列のデータ型と同じである必要があります。

ケース 1 lpszSQL = NULL

レコードセットの選択は、呼び出 GetDefaultSQL し時に返される内容 CRecordset::Open によって異なります。 ケース 2 ~ 5 では、考えられる文字列が記述されています。

ケース 2 lpszSQL = テーブル名

レコードセットは、レコード フィールド交換 (RFX) を使用して、レコードセット クラスの のオーバーライドで RFX 関数呼び出しで指定された列名から列リストを作成します DoFieldExchange 。 ウィザードを使用してレコードセット クラスを宣言した場合、このケースの結果はケース 1 と同じです (ウィザードで指定したのと同じテーブル名を渡す場合)。 ウィザードを使用してクラスを記述しない場合は、大文字と小文字の区別ステートメントを作成する最も簡単なSQLケース 2 です。

次の例では、MFC SQLレコードを選択するステートメントを作成します。 フレームワークがメンバー関数を GetDefaultSQL 呼び出す場合、関数はテーブルの名前 を返します SECTION

CString CEnrollSet::GetDefaultSQL()
{
    return "SECTION";
}

SELECTステートメントの列の名前を取得SQL、フレームワークは メンバー関数を 呼び出します。

void CEnrollSet::DoFieldExchange(CFieldExchange* pFX)
{
    pFX->SetFieldType(CFieldExchange::outputColumn);
    RFX_Text(pFX, "CourseID", m_strCourseID);
    RFX_Text(pFX, "InstructorID", m_strInstructorID);
    RFX_Text(pFX, "RoomNo", m_strRoomNo);
    RFX_Text(pFX, "Schedule", m_strSchedule);
    RFX_Text(pFX, "SectionNo", m_strSectionNo);
}

完了すると、SQLは次のように表示されます。

SELECT CourseID, InstructorID, RoomNo, Schedule, SectionNo
    FROM SECTION

ケース 3 lpszSQL = SELECT/FROM ステートメント

列リストは、RFX に依存して自動的に構築するのではなく、手で指定します。 次の場合にこれを行う必要があります。

  • SELECT の後に DISTINCT キーワードを 指定 する場合

    列リストは、 に一覧表示されているのと同じ順序で列名と型と一致する必要があります DoFieldExchange

  • 列をバインドおよび取得するために RFX に依存するのではなく、ODBC 関数を使用して列の値を手動で取得 ::SQLGetData する理由があります。

    たとえば、アプリケーションの顧客がアプリケーションの分散後にデータベース テーブルに追加した新しい列に対応したい場合があります。 これらの追加のフィールド データ メンバーを追加する必要があります。これは、ウィザードでクラスを宣言した時点では知られていませんでした。

    列の一覧は、 に記載されているのと同じ順序で列の名前と型に一致し、その後に手動でバインドされた列の名前 DoFieldExchange と一致する必要があります。 詳細については、「レコードセット : データ列の動的バインド (ODBC)」を参照してください

  • FROM 句で複数のテーブルを指定してテーブルを 結合する場合

    詳細と例については、「レコードセット : 結合の実行 (ODBC)」を参照してください

ケース 4 lpszSQL = SELECT/FROM Plus WHERE または ORDER BY

列リスト (内の RFX 呼び出しに基づく) 、テーブル リスト、WHERE 句や ORDER BY 句の内容を指定 DoFieldExchange します。 DoFieldExchange この方法でWHERE 句ORDER BY句を指定する場合は、 や を 使用しない。

ケース 5 lpszSQL = ストアド プロシージャ呼び出し

定義済みのクエリ (Microsoft SQL Server データベースのストアド プロシージャなど) を呼び出す必要がある場合は、lpszSQLに渡す文字列にCALLステートメントを記述する必要があります。 ウィザードでは、定義済みのクエリを呼び出すレコードセット クラスの宣言はサポートされていません。 すべての定義済みクエリがレコードを返す場合ではありません。

定義済みのクエリがレコードを返していない場合は、メンバー関数を直接 CDatabase 使用 ExecuteSQL できます。 レコードを返す定義済みのクエリの場合は、プロシージャが返す列に対して RFX 呼び出しを に手動で書 DoFieldExchange き込む必要があります。 RFX 呼び出しは、定義済みのクエリと同じ順序で、同じ型を返す必要があります。 詳細については、「レコードセット: 定義済みクエリのクラスの宣言 (ODBC)」を参照してください

こちらもご覧ください

SQL: SQL C++ データ型 (ODBC)
SQL: ダイレクト SQL呼び出しの作成 (ODBC)